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}