bitcoin_internals/
serde.rs

1//! Contains extensions of `serde` and internal reexports.
2
3#[doc(hidden)]
4pub use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
5
6/// Converts given error type to a type implementing [`de::Error`].
7///
8/// This is used in [`Deserialize`] implementations to convert specialized errors into serde
9/// errors.
10pub trait IntoDeError: Sized {
11    /// Converts to deserializer error possibly outputting vague message.
12    ///
13    /// This method is allowed to return a vague error message if the error type doesn't contain
14    /// enough information to explain the error precisely.
15    fn into_de_error<E: de::Error>(self, expected: Option<&dyn de::Expected>) -> E;
16
17    /// Converts to deserializer error without outputting vague message.
18    ///
19    /// If the error type doesn't contain enough information to explain the error precisely this
20    /// should return `Err(self)` allowing the caller to use its information instead.
21    fn try_into_de_error<E>(self, expected: Option<&dyn de::Expected>) -> Result<E, Self>
22    where
23        E: de::Error,
24    {
25        Ok(self.into_de_error(expected))
26    }
27}
28
29mod impls {
30    use super::*;
31
32    impl IntoDeError for core::convert::Infallible {
33        fn into_de_error<E: de::Error>(self, _expected: Option<&dyn de::Expected>) -> E {
34            match self {}
35        }
36    }
37
38    impl IntoDeError for core::num::ParseIntError {
39        fn into_de_error<E: de::Error>(self, expected: Option<&dyn de::Expected>) -> E {
40            self.try_into_de_error(expected).unwrap_or_else(|_| {
41                let expected = expected.unwrap_or(&"an integer");
42
43                E::custom(format_args!("invalid string, expected {}", expected))
44            })
45        }
46
47        fn try_into_de_error<E>(self, expected: Option<&dyn de::Expected>) -> Result<E, Self>
48        where
49            E: de::Error,
50        {
51            use core::num::IntErrorKind::Empty;
52
53            let expected = expected.unwrap_or(&"an integer");
54
55            match self.kind() {
56                Empty => Ok(E::invalid_value(de::Unexpected::Str(""), expected)),
57                _ => Err(self),
58            }
59        }
60    }
61}
62
63/// Implements `serde::Serialize` by way of `Display`.
64///
65/// `$name` is required to implement `core::fmt::Display`.
66#[macro_export]
67macro_rules! serde_string_serialize_impl {
68    ($name:ty, $expecting:literal) => {
69        impl $crate::serde::Serialize for $name {
70            fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
71            where
72                S: $crate::serde::Serializer,
73            {
74                serializer.collect_str(&self)
75            }
76        }
77    };
78}
79
80/// Implements `serde::Deserialize` by way of `FromStr`.
81///
82/// `$name` is required to implement `core::str::FromStr`.
83#[macro_export]
84macro_rules! serde_string_deserialize_impl {
85    ($name:ty, $expecting:literal) => {
86        impl<'de> $crate::serde::Deserialize<'de> for $name {
87            fn deserialize<D>(deserializer: D) -> core::result::Result<$name, D::Error>
88            where
89                D: $crate::serde::de::Deserializer<'de>,
90            {
91                use core::fmt::Formatter;
92
93                struct Visitor;
94                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
95                    type Value = $name;
96
97                    fn expecting(&self, f: &mut Formatter) -> core::fmt::Result {
98                        f.write_str($expecting)
99                    }
100
101                    fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
102                    where
103                        E: $crate::serde::de::Error,
104                    {
105                        v.parse::<$name>().map_err(E::custom)
106                    }
107                }
108
109                deserializer.deserialize_str(Visitor)
110            }
111        }
112    };
113}
114
115/// Implements `serde::Serialize` and `Deserialize` by way of `Display` and `FromStr` respectively.
116///
117/// `$name` is required to implement `core::fmt::Display` and `core::str::FromStr`.
118#[macro_export]
119macro_rules! serde_string_impl {
120    ($name:ty, $expecting:literal) => {
121        $crate::serde_string_deserialize_impl!($name, $expecting);
122        $crate::serde_string_serialize_impl!($name, $expecting);
123    };
124}
125
126/// A combination macro where the human-readable serialization is done like
127/// serde_string_impl and the non-human-readable impl is done as a struct.
128#[macro_export]
129macro_rules! serde_struct_human_string_impl {
130    ($name:ident, $expecting:literal, $($fe:ident),*) => (
131        impl<'de> $crate::serde::Deserialize<'de> for $name {
132            fn deserialize<D>(deserializer: D) -> core::result::Result<$name, D::Error>
133            where
134                D: $crate::serde::de::Deserializer<'de>,
135            {
136                if deserializer.is_human_readable() {
137                    use core::fmt::Formatter;
138
139                    struct Visitor;
140                    impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
141                        type Value = $name;
142
143                        fn expecting(&self, f: &mut Formatter) -> core::fmt::Result {
144                            f.write_str($expecting)
145                        }
146
147                        fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
148                        where
149                            E: $crate::serde::de::Error,
150                        {
151                            v.parse::<$name>().map_err(E::custom)
152                        }
153
154                    }
155
156                    deserializer.deserialize_str(Visitor)
157                } else {
158                    use core::fmt::Formatter;
159                    use $crate::serde::de::IgnoredAny;
160
161                    #[allow(non_camel_case_types)]
162                    enum Enum { Unknown__Field, $($fe),* }
163
164                    struct EnumVisitor;
165                    impl<'de> $crate::serde::de::Visitor<'de> for EnumVisitor {
166                        type Value = Enum;
167
168                        fn expecting(&self, f: &mut Formatter) -> core::fmt::Result {
169                            f.write_str("a field name")
170                        }
171
172                        fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
173                        where
174                            E: $crate::serde::de::Error,
175                        {
176                            match v {
177                                $(
178                                stringify!($fe) => Ok(Enum::$fe)
179                                ),*,
180                                _ => Ok(Enum::Unknown__Field)
181                            }
182                        }
183                    }
184
185                    impl<'de> $crate::serde::Deserialize<'de> for Enum {
186                        fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
187                        where
188                            D: $crate::serde::de::Deserializer<'de>,
189                        {
190                            deserializer.deserialize_str(EnumVisitor)
191                        }
192                    }
193
194                    struct Visitor;
195
196                    impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
197                        type Value = $name;
198
199                        fn expecting(&self, f: &mut Formatter) -> core::fmt::Result {
200                            f.write_str("a struct")
201                        }
202
203                        fn visit_seq<V>(self, mut seq: V) -> core::result::Result<Self::Value, V::Error>
204                        where
205                            V: $crate::serde::de::SeqAccess<'de>,
206                        {
207                            use $crate::serde::de::Error;
208
209                            let length = 0;
210                            $(
211                                let $fe = seq.next_element()?.ok_or_else(|| {
212                                    Error::invalid_length(length, &self)
213                                })?;
214                                #[allow(unused_variables)]
215                                let length = length + 1;
216                            )*
217
218                            let ret = $name {
219                                $($fe),*
220                            };
221
222                            Ok(ret)
223                        }
224
225                        fn visit_map<A>(self, mut map: A) -> core::result::Result<Self::Value, A::Error>
226                        where
227                            A: $crate::serde::de::MapAccess<'de>,
228                        {
229                            use $crate::serde::de::Error;
230
231                            $(let mut $fe = None;)*
232
233                            loop {
234                                match map.next_key::<Enum>()? {
235                                    Some(Enum::Unknown__Field) => {
236                                        map.next_value::<IgnoredAny>()?;
237                                    }
238                                    $(
239                                        Some(Enum::$fe) => {
240                                            $fe = Some(map.next_value()?);
241                                        }
242                                    )*
243                                    None => { break; }
244                                }
245                            }
246
247                            $(
248                                let $fe = match $fe {
249                                    Some(x) => x,
250                                    None => return Err(A::Error::missing_field(stringify!($fe))),
251                                };
252                            )*
253
254                            let ret = $name {
255                                $($fe),*
256                            };
257
258                            Ok(ret)
259                        }
260                    }
261                    // end type defs
262
263                    static FIELDS: &'static [&'static str] = &[$(stringify!($fe)),*];
264
265                    deserializer.deserialize_struct(stringify!($name), FIELDS, Visitor)
266                }
267            }
268        }
269
270        impl $crate::serde::Serialize for $name {
271            fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
272            where
273                S: $crate::serde::Serializer,
274            {
275                if serializer.is_human_readable() {
276                    serializer.collect_str(&self)
277                } else {
278                    use $crate::serde::ser::SerializeStruct;
279
280                    // Only used to get the struct length.
281                    static FIELDS: &'static [&'static str] = &[$(stringify!($fe)),*];
282
283                    let mut st = serializer.serialize_struct(stringify!($name), FIELDS.len())?;
284
285                    $(
286                        st.serialize_field(stringify!($fe), &self.$fe)?;
287                    )*
288
289                    st.end()
290                }
291            }
292        }
293    )
294}
295
296/// Does round trip test to/from serde value.
297#[cfg(feature = "test-serde")]
298#[macro_export]
299macro_rules! serde_round_trip (
300    ($var:expr) => ({
301        use serde_json;
302
303        let encoded = $crate::serde_json::to_value(&$var).expect("serde_json failed to encode");
304        let decoded = $crate::serde_json::from_value(encoded).expect("serde_json failed to decode");
305        assert_eq!($var, decoded);
306
307        let encoded = $crate::bincode::serialize(&$var).expect("bincode failed to encode");
308        let decoded = $crate::bincode::deserialize(&encoded).expect("bincode failed to decode");
309        assert_eq!($var, decoded);
310    })
311);