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