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}