similar_asserts/
serde_impl.rs

1use std::fmt;
2
3use serde::ser::{
4    SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
5    SerializeTupleStruct, SerializeTupleVariant,
6};
7use serde::{Serialize, Serializer};
8
9pub struct Debug<'a, T: Serialize + ?Sized>(pub &'a T);
10
11impl<'a, T: Serialize + ?Sized> fmt::Debug for Debug<'a, T> {
12    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13        self.0.serialize(DebugSerializer(f))?;
14        Ok(())
15    }
16}
17
18macro_rules! simple_serialize {
19    ($name:ident, $type:ty) => {
20        fn $name(self, v: $type) -> Result<Self::Ok, Self::Error> {
21            fmt::Debug::fmt(&v, self.0)
22        }
23    };
24}
25
26pub struct DebugSerializer<'a, 'b: 'a>(pub &'a mut fmt::Formatter<'b>);
27
28impl<'a, 'b: 'a> Serializer for DebugSerializer<'a, 'b> {
29    type Ok = ();
30    type Error = fmt::Error;
31
32    type SerializeSeq = SeqSerializer<'a, 'b>;
33    type SerializeTuple = TupleSerializer<'a, 'b>;
34    type SerializeTupleStruct = TupleSerializer<'a, 'b>;
35    type SerializeTupleVariant = TupleSerializer<'a, 'b>;
36    type SerializeMap = MapSerializer<'a, 'b>;
37    type SerializeStruct = StructSerializer<'a, 'b>;
38    type SerializeStructVariant = StructSerializer<'a, 'b>;
39
40    simple_serialize!(serialize_bool, bool);
41    simple_serialize!(serialize_i8, i8);
42    simple_serialize!(serialize_i16, i16);
43    simple_serialize!(serialize_i32, i32);
44    simple_serialize!(serialize_i64, i64);
45    simple_serialize!(serialize_i128, i128);
46    simple_serialize!(serialize_u8, u8);
47    simple_serialize!(serialize_u16, u16);
48    simple_serialize!(serialize_u32, u32);
49    simple_serialize!(serialize_u64, u64);
50    simple_serialize!(serialize_u128, u128);
51    simple_serialize!(serialize_f32, f32);
52    simple_serialize!(serialize_f64, f64);
53    simple_serialize!(serialize_char, char);
54    simple_serialize!(serialize_str, &str);
55    simple_serialize!(serialize_bytes, &[u8]);
56
57    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
58        self.serialize_unit_struct("None")
59    }
60
61    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
62        self.serialize_newtype_struct("Some", value)
63    }
64
65    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
66        write!(self.0, "()")
67    }
68
69    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
70        SerializeTupleStruct::end(self.serialize_tuple_struct(name, 0)?)
71    }
72
73    fn serialize_unit_variant(
74        self,
75        _name: &'static str,
76        _variant_index: u32,
77        variant: &'static str,
78    ) -> Result<Self::Ok, Self::Error> {
79        self.serialize_unit_struct(variant)
80    }
81
82    fn serialize_newtype_struct<T: ?Sized + Serialize>(
83        self,
84        name: &'static str,
85        value: &T,
86    ) -> Result<Self::Ok, Self::Error> {
87        let mut tuple = self.serialize_tuple_struct(name, 1)?;
88        SerializeTupleStruct::serialize_field(&mut tuple, value)?;
89        SerializeTupleStruct::end(tuple)
90    }
91
92    fn serialize_newtype_variant<T: ?Sized + Serialize>(
93        self,
94        _name: &'static str,
95        _variant_index: u32,
96        variant: &'static str,
97        value: &T,
98    ) -> Result<Self::Ok, Self::Error> {
99        self.serialize_newtype_struct(variant, value)
100    }
101
102    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
103        Ok(SeqSerializer(self.0.debug_list()))
104    }
105
106    fn serialize_tuple_struct(
107        self,
108        name: &'static str,
109        _len: usize,
110    ) -> Result<Self::SerializeTuple, Self::Error> {
111        Ok(TupleSerializer(self.0.debug_tuple(name)))
112    }
113
114    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
115        self.serialize_tuple_struct("", len)
116    }
117
118    fn serialize_tuple_variant(
119        self,
120        _name: &'static str,
121        _variant_index: u32,
122        variant: &'static str,
123        len: usize,
124    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
125        self.serialize_tuple_struct(variant, len)
126    }
127
128    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
129        Ok(MapSerializer(self.0.debug_map()))
130    }
131
132    fn serialize_struct(
133        self,
134        name: &'static str,
135        _len: usize,
136    ) -> Result<Self::SerializeStruct, Self::Error> {
137        Ok(StructSerializer(self.0.debug_struct(name)))
138    }
139
140    fn serialize_struct_variant(
141        self,
142        _name: &'static str,
143        _variant_index: u32,
144        variant: &'static str,
145        len: usize,
146    ) -> Result<Self::SerializeStructVariant, Self::Error> {
147        self.serialize_struct(variant, len)
148    }
149}
150
151pub struct SeqSerializer<'a, 'b: 'a>(fmt::DebugList<'a, 'b>);
152
153impl<'a, 'b: 'a> SerializeSeq for SeqSerializer<'a, 'b> {
154    type Ok = ();
155    type Error = fmt::Error;
156
157    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
158        self.0.entry(&Debug(value));
159        Ok(())
160    }
161
162    fn end(mut self) -> Result<(), Self::Error> {
163        self.0.finish()
164    }
165}
166
167pub struct TupleSerializer<'a, 'b: 'a>(fmt::DebugTuple<'a, 'b>);
168
169impl<'a, 'b: 'a> SerializeTuple for TupleSerializer<'a, 'b> {
170    type Ok = ();
171    type Error = fmt::Error;
172
173    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
174        self.0.field(&Debug(value));
175        Ok(())
176    }
177
178    fn end(mut self) -> Result<(), Self::Error> {
179        self.0.finish()
180    }
181}
182
183impl<'a, 'b: 'a> SerializeTupleStruct for TupleSerializer<'a, 'b> {
184    type Ok = ();
185    type Error = fmt::Error;
186
187    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
188        SerializeTuple::serialize_element(self, value)
189    }
190
191    fn end(self) -> Result<(), Self::Error> {
192        SerializeTuple::end(self)
193    }
194}
195
196impl<'a, 'b: 'a> SerializeTupleVariant for TupleSerializer<'a, 'b> {
197    type Ok = ();
198    type Error = fmt::Error;
199
200    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
201        SerializeTuple::serialize_element(self, value)
202    }
203
204    fn end(self) -> Result<(), Self::Error> {
205        SerializeTuple::end(self)
206    }
207}
208
209pub struct MapSerializer<'a, 'b: 'a>(fmt::DebugMap<'a, 'b>);
210
211impl<'a, 'b: 'a> SerializeMap for MapSerializer<'a, 'b> {
212    type Ok = ();
213    type Error = fmt::Error;
214
215    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error> {
216        self.0.key(&Debug(key));
217        Ok(())
218    }
219
220    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
221        self.0.value(&Debug(value));
222        Ok(())
223    }
224
225    fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(
226        &mut self,
227        key: &K,
228        value: &V,
229    ) -> Result<(), Self::Error> {
230        self.0.entry(&Debug(key), &Debug(value));
231        Ok(())
232    }
233
234    fn end(mut self) -> Result<(), Self::Error> {
235        self.0.finish()
236    }
237}
238
239pub struct StructSerializer<'a, 'b: 'a>(fmt::DebugStruct<'a, 'b>);
240
241impl<'a, 'b: 'a> SerializeStruct for StructSerializer<'a, 'b> {
242    type Ok = ();
243    type Error = fmt::Error;
244
245    fn serialize_field<T: ?Sized + Serialize>(
246        &mut self,
247        key: &'static str,
248        value: &T,
249    ) -> Result<(), Self::Error> {
250        self.0.field(key, &Debug(value));
251        Ok(())
252    }
253
254    fn end(mut self) -> Result<(), Self::Error> {
255        self.0.finish()
256    }
257}
258
259impl<'a, 'b: 'a> SerializeStructVariant for StructSerializer<'a, 'b> {
260    type Ok = ();
261    type Error = fmt::Error;
262
263    fn serialize_field<T: ?Sized + Serialize>(
264        &mut self,
265        key: &'static str,
266        value: &T,
267    ) -> Result<(), Self::Error> {
268        SerializeStruct::serialize_field(self, key, value)
269    }
270
271    fn end(self) -> Result<(), Self::Error> {
272        SerializeStruct::end(self)
273    }
274}
275
276#[doc(hidden)]
277#[macro_export]
278macro_rules! __assert_serde_eq {
279    (
280        $method:ident,
281        $left_label:ident,
282        $left:expr,
283        $right_label:ident,
284        $right:expr,
285        $hint_suffix:expr
286    ) => {{
287        match (&($left), &($right)) {
288            (left_val, right_val) => {
289                if !(*left_val == *right_val) {
290                    use std::borrow::Cow;
291                    use $crate::serde_impl::Debug;
292                    let left_label = stringify!($left_label);
293                    let right_label = stringify!($right_label);
294                    let left_short = Some(Cow::Owned(format!("{:?}", Debug(left_val))));
295                    let right_short = Some(Cow::Owned(format!("{:?}", Debug(right_val))));
296                    let left_expanded = Some(Cow::Owned(format!("{:#?}", Debug(left_val))));
297                    let right_expanded = Some(Cow::Owned(format!("{:#?}", Debug(right_val))));
298                    let diff = $crate::SimpleDiff::__from_macro(
299                        left_short,
300                        right_short,
301                        left_expanded,
302                        right_expanded,
303                        left_label,
304                        right_label,
305                    );
306                    diff.fail_assertion(&$hint_suffix);
307                }
308            }
309        }
310    }};
311}
312
313/// Asserts that two expressions are equal to each other (using [`PartialEq`]) using [`Serialize`](serde::Serialize) for comparision.
314///
315/// On panic, this macro will print the values of the expressions with their
316/// serde [`Serialize`](serde::Serialize) representations rendered in the same
317/// format that [`std::fmt::Debug`] would with a colorized diff of the changes in
318/// the debug output.
319///
320/// Like [`assert!`], this macro has a second form, where a custom panic
321/// message can be provided.
322///
323/// ```rust
324/// use similar_asserts::assert_serde_eq;
325/// assert_serde_eq!((1..3).collect::<Vec<_>>(), vec![1, 2]);
326/// ```
327///
328/// This requires the `serde` feature.
329#[macro_export]
330#[cfg(feature = "serde")]
331macro_rules! assert_serde_eq {
332    ($left_label:ident: $left:expr, $right_label:ident: $right:expr $(,)?) => ({
333        $crate::__assert_serde_eq!(make_serde_diff, $left_label, $left, $right_label, $right, "");
334    });
335    ($left_label:ident: $left:expr, $right_label:ident: $right:expr, $($arg:tt)*) => ({
336        $crate::__assert_serde_eq!(make_serde_diff, $left_label, $left, $right_label, $right, format_args!(": {}", format_args!($($arg)*)));
337    });
338    ($left:expr, $right:expr $(,)?) => ({
339        $crate::assert_serde_eq!(left: $left, right: $right);
340    });
341    ($left:expr, $right:expr, $($arg:tt)*) => ({
342        $crate::assert_serde_eq!(left: $left, right: $right, $($arg)*);
343    });
344}