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/// ```edition2021
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/// ```edition2021
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/// ```edition2021
82/// # use serde::forward_to_deserialize_any;
83/// # use serde::de::{value, Deserializer, Visitor};
84/// # use std::marker::PhantomData;
85/// #
86/// # struct MyDeserializer<V>(PhantomData<V>);
87/// #
88/// # impl<'q, V> Deserializer<'q> for MyDeserializer<V> {
89/// #     type Error = value::Error;
90/// #
91/// #     fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
92/// #     where
93/// #         W: Visitor<'q>,
94/// #     {
95/// #         unimplemented!()
96/// #     }
97/// #
98/// forward_to_deserialize_any! {
99///     <W: Visitor<'q>>
100///     bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
101///     bytes byte_buf option unit unit_struct newtype_struct seq tuple
102///     tuple_struct map struct enum identifier ignored_any
103/// }
104/// # }
105/// ```
106///
107/// [`Deserializer`]: trait.Deserializer.html
108/// [`Visitor`]: de/trait.Visitor.html
109/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any
110#[macro_export(local_inner_macros)]
111macro_rules! forward_to_deserialize_any {
112    (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
113        $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
114    };
115    // This case must be after the previous one.
116    ($($func:ident)*) => {
117        $(forward_to_deserialize_any_helper!{$func<'de, V>})*
118    };
119}
120
121#[doc(hidden)]
122#[macro_export]
123macro_rules! forward_to_deserialize_any_method {
124    ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => {
125        #[inline]
126        fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::__private::Result<$v::Value, <Self as $crate::de::Deserializer<$l>>::Error>
127        where
128            $v: $crate::de::Visitor<$l>,
129        {
130            $(
131                let _ = $arg;
132            )*
133            self.deserialize_any(visitor)
134        }
135    };
136}
137
138#[doc(hidden)]
139#[macro_export(local_inner_macros)]
140macro_rules! forward_to_deserialize_any_helper {
141    (bool<$l:tt, $v:ident>) => {
142        forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
143    };
144    (i8<$l:tt, $v:ident>) => {
145        forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()}
146    };
147    (i16<$l:tt, $v:ident>) => {
148        forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()}
149    };
150    (i32<$l:tt, $v:ident>) => {
151        forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()}
152    };
153    (i64<$l:tt, $v:ident>) => {
154        forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()}
155    };
156    (i128<$l:tt, $v:ident>) => {
157        forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()}
158    };
159    (u8<$l:tt, $v:ident>) => {
160        forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()}
161    };
162    (u16<$l:tt, $v:ident>) => {
163        forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()}
164    };
165    (u32<$l:tt, $v:ident>) => {
166        forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()}
167    };
168    (u64<$l:tt, $v:ident>) => {
169        forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()}
170    };
171    (u128<$l:tt, $v:ident>) => {
172        forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()}
173    };
174    (f32<$l:tt, $v:ident>) => {
175        forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()}
176    };
177    (f64<$l:tt, $v:ident>) => {
178        forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()}
179    };
180    (char<$l:tt, $v:ident>) => {
181        forward_to_deserialize_any_method!{deserialize_char<$l, $v>()}
182    };
183    (str<$l:tt, $v:ident>) => {
184        forward_to_deserialize_any_method!{deserialize_str<$l, $v>()}
185    };
186    (string<$l:tt, $v:ident>) => {
187        forward_to_deserialize_any_method!{deserialize_string<$l, $v>()}
188    };
189    (bytes<$l:tt, $v:ident>) => {
190        forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()}
191    };
192    (byte_buf<$l:tt, $v:ident>) => {
193        forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()}
194    };
195    (option<$l:tt, $v:ident>) => {
196        forward_to_deserialize_any_method!{deserialize_option<$l, $v>()}
197    };
198    (unit<$l:tt, $v:ident>) => {
199        forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()}
200    };
201    (unit_struct<$l:tt, $v:ident>) => {
202        forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)}
203    };
204    (newtype_struct<$l:tt, $v:ident>) => {
205        forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)}
206    };
207    (seq<$l:tt, $v:ident>) => {
208        forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()}
209    };
210    (tuple<$l:tt, $v:ident>) => {
211        forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)}
212    };
213    (tuple_struct<$l:tt, $v:ident>) => {
214        forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)}
215    };
216    (map<$l:tt, $v:ident>) => {
217        forward_to_deserialize_any_method!{deserialize_map<$l, $v>()}
218    };
219    (struct<$l:tt, $v:ident>) => {
220        forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])}
221    };
222    (enum<$l:tt, $v:ident>) => {
223        forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])}
224    };
225    (identifier<$l:tt, $v:ident>) => {
226        forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()}
227    };
228    (ignored_any<$l:tt, $v:ident>) => {
229        forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()}
230    };
231}