serde_core/macros.rs
1// Super explicit first paragraph because this shows up at the top level and
2// trips up people who are just looking for basic Serialize / Deserialize
3// documentation.
4/// Helper macro when implementing the `Deserializer` part of a new data format
5/// for Serde.
6///
7/// Some [`Deserializer`] implementations for self-describing formats do not
8/// care what hint the [`Visitor`] gives them, they just want to blindly call
9/// the [`Visitor`] method corresponding to the data they can tell is in the
10/// input. This requires repetitive implementations of all the [`Deserializer`]
11/// trait methods.
12///
13/// ```edition2021
14/// # use serde::forward_to_deserialize_any;
15/// # use serde::de::{value, Deserializer, Visitor};
16/// #
17/// # struct MyDeserializer;
18/// #
19/// # impl<'de> Deserializer<'de> for MyDeserializer {
20/// # type Error = value::Error;
21/// #
22/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
23/// # where
24/// # V: Visitor<'de>,
25/// # {
26/// # unimplemented!()
27/// # }
28/// #
29/// #[inline]
30/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
31/// where
32/// V: Visitor<'de>,
33/// {
34/// self.deserialize_any(visitor)
35/// }
36/// #
37/// # forward_to_deserialize_any! {
38/// # i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
39/// # bytes byte_buf option unit unit_struct newtype_struct seq tuple
40/// # tuple_struct map struct enum identifier ignored_any
41/// # }
42/// # }
43/// ```
44///
45/// The `forward_to_deserialize_any!` macro implements these simple forwarding
46/// methods so that they forward directly to [`Deserializer::deserialize_any`].
47/// You can choose which methods to forward.
48///
49/// ```edition2021
50/// # use serde::forward_to_deserialize_any;
51/// # use serde::de::{value, Deserializer, Visitor};
52/// #
53/// # struct MyDeserializer;
54/// #
55/// impl<'de> Deserializer<'de> for MyDeserializer {
56/// # type Error = value::Error;
57/// #
58/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
59/// where
60/// V: Visitor<'de>,
61/// {
62/// /* ... */
63/// # let _ = visitor;
64/// # unimplemented!()
65/// }
66///
67/// forward_to_deserialize_any! {
68/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
69/// bytes byte_buf option unit unit_struct newtype_struct seq tuple
70/// tuple_struct map struct enum identifier ignored_any
71/// }
72/// }
73/// ```
74///
75/// The macro assumes the convention that your `Deserializer` lifetime parameter
76/// is called `'de` and that the `Visitor` type parameters on each method are
77/// called `V`. A different type parameter and a different lifetime can be
78/// specified explicitly if necessary.
79///
80/// ```edition2021
81/// # use serde::forward_to_deserialize_any;
82/// # use serde::de::{value, Deserializer, Visitor};
83/// # use std::marker::PhantomData;
84/// #
85/// # struct MyDeserializer<V>(PhantomData<V>);
86/// #
87/// # impl<'q, V> Deserializer<'q> for MyDeserializer<V> {
88/// # type Error = value::Error;
89/// #
90/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
91/// # where
92/// # W: Visitor<'q>,
93/// # {
94/// # unimplemented!()
95/// # }
96/// #
97/// forward_to_deserialize_any! {
98/// <W: Visitor<'q>>
99/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
100/// bytes byte_buf option unit unit_struct newtype_struct seq tuple
101/// tuple_struct map struct enum identifier ignored_any
102/// }
103/// # }
104/// ```
105///
106/// [`Deserializer`]: crate::Deserializer
107/// [`Visitor`]: crate::de::Visitor
108/// [`Deserializer::deserialize_any`]: crate::Deserializer::deserialize_any
109#[macro_export(local_inner_macros)]
110macro_rules! forward_to_deserialize_any {
111 (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
112 $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
113 };
114 // This case must be after the previous one.
115 ($($func:ident)*) => {
116 $(forward_to_deserialize_any_helper!{$func<'de, V>})*
117 };
118}
119
120#[doc(hidden)]
121#[macro_export]
122macro_rules! forward_to_deserialize_any_method {
123 ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => {
124 #[inline]
125 fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::__private::Result<$v::Value, <Self as $crate::de::Deserializer<$l>>::Error>
126 where
127 $v: $crate::de::Visitor<$l>,
128 {
129 $(
130 let _ = $arg;
131 )*
132 self.deserialize_any(visitor)
133 }
134 };
135}
136
137#[doc(hidden)]
138#[macro_export(local_inner_macros)]
139macro_rules! forward_to_deserialize_any_helper {
140 (bool<$l:tt, $v:ident>) => {
141 forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
142 };
143 (i8<$l:tt, $v:ident>) => {
144 forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()}
145 };
146 (i16<$l:tt, $v:ident>) => {
147 forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()}
148 };
149 (i32<$l:tt, $v:ident>) => {
150 forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()}
151 };
152 (i64<$l:tt, $v:ident>) => {
153 forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()}
154 };
155 (i128<$l:tt, $v:ident>) => {
156 forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()}
157 };
158 (u8<$l:tt, $v:ident>) => {
159 forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()}
160 };
161 (u16<$l:tt, $v:ident>) => {
162 forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()}
163 };
164 (u32<$l:tt, $v:ident>) => {
165 forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()}
166 };
167 (u64<$l:tt, $v:ident>) => {
168 forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()}
169 };
170 (u128<$l:tt, $v:ident>) => {
171 forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()}
172 };
173 (f32<$l:tt, $v:ident>) => {
174 forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()}
175 };
176 (f64<$l:tt, $v:ident>) => {
177 forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()}
178 };
179 (char<$l:tt, $v:ident>) => {
180 forward_to_deserialize_any_method!{deserialize_char<$l, $v>()}
181 };
182 (str<$l:tt, $v:ident>) => {
183 forward_to_deserialize_any_method!{deserialize_str<$l, $v>()}
184 };
185 (string<$l:tt, $v:ident>) => {
186 forward_to_deserialize_any_method!{deserialize_string<$l, $v>()}
187 };
188 (bytes<$l:tt, $v:ident>) => {
189 forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()}
190 };
191 (byte_buf<$l:tt, $v:ident>) => {
192 forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()}
193 };
194 (option<$l:tt, $v:ident>) => {
195 forward_to_deserialize_any_method!{deserialize_option<$l, $v>()}
196 };
197 (unit<$l:tt, $v:ident>) => {
198 forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()}
199 };
200 (unit_struct<$l:tt, $v:ident>) => {
201 forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)}
202 };
203 (newtype_struct<$l:tt, $v:ident>) => {
204 forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)}
205 };
206 (seq<$l:tt, $v:ident>) => {
207 forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()}
208 };
209 (tuple<$l:tt, $v:ident>) => {
210 forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)}
211 };
212 (tuple_struct<$l:tt, $v:ident>) => {
213 forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)}
214 };
215 (map<$l:tt, $v:ident>) => {
216 forward_to_deserialize_any_method!{deserialize_map<$l, $v>()}
217 };
218 (struct<$l:tt, $v:ident>) => {
219 forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])}
220 };
221 (enum<$l:tt, $v:ident>) => {
222 forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])}
223 };
224 (identifier<$l:tt, $v:ident>) => {
225 forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()}
226 };
227 (ignored_any<$l:tt, $v:ident>) => {
228 forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()}
229 };
230}