insta/content/
serialization.rs

1use std::cmp::Ordering;
2use std::marker::PhantomData;
3
4use crate::content::Content;
5
6use serde::{ser, Serialize, Serializer};
7
8#[derive(PartialEq, Debug)]
9pub enum Key<'a> {
10    Bool(bool),
11    U64(u64),
12    I64(i64),
13    F64(f64),
14    U128(u128),
15    I128(i128),
16    Str(&'a str),
17    Bytes(&'a [u8]),
18    Other,
19}
20
21impl Key<'_> {
22    /// Needed because [`std::mem::discriminant`] is not [`Ord`]
23    fn discriminant(&self) -> usize {
24        match self {
25            Key::Bool(_) => 1,
26            Key::U64(_) => 2,
27            Key::I64(_) => 3,
28            Key::F64(_) => 4,
29            Key::U128(_) => 5,
30            Key::I128(_) => 6,
31            Key::Str(_) => 7,
32            Key::Bytes(_) => 8,
33            Key::Other => 9,
34        }
35    }
36}
37
38impl Eq for Key<'_> {}
39
40impl Ord for Key<'_> {
41    fn cmp(&self, other: &Self) -> Ordering {
42        let self_discriminant = self.discriminant();
43        let other_discriminant = other.discriminant();
44        match Ord::cmp(&self_discriminant, &other_discriminant) {
45            Ordering::Equal => match (self, other) {
46                (Key::Bool(a), Key::Bool(b)) => Ord::cmp(a, b),
47                (Key::U64(a), Key::U64(b)) => Ord::cmp(a, b),
48                (Key::I64(a), Key::I64(b)) => Ord::cmp(a, b),
49                (Key::F64(a), Key::F64(b)) => f64_total_cmp(*a, *b),
50                (Key::U128(a), Key::U128(b)) => Ord::cmp(a, b),
51                (Key::I128(a), Key::I128(b)) => Ord::cmp(a, b),
52                (Key::Str(a), Key::Str(b)) => Ord::cmp(a, b),
53                (Key::Bytes(a), Key::Bytes(b)) => Ord::cmp(a, b),
54                _ => Ordering::Equal,
55            },
56            cmp => cmp,
57        }
58    }
59}
60
61impl PartialOrd for Key<'_> {
62    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
63        Some(self.cmp(other))
64    }
65}
66
67fn f64_total_cmp(left: f64, right: f64) -> Ordering {
68    // this is taken from f64::total_cmp on newer rust versions
69    let mut left = left.to_bits() as i64;
70    let mut right = right.to_bits() as i64;
71    left ^= (((left >> 63) as u64) >> 1) as i64;
72    right ^= (((right >> 63) as u64) >> 1) as i64;
73    left.cmp(&right)
74}
75
76impl Content {
77    pub(crate) fn as_key(&self) -> Key<'_> {
78        match *self.resolve_inner() {
79            Content::Bool(val) => Key::Bool(val),
80            Content::Char(val) => Key::U64(val as u64),
81            Content::U16(val) => Key::U64(val.into()),
82            Content::U32(val) => Key::U64(val.into()),
83            Content::U64(val) => Key::U64(val),
84            Content::U128(val) => Key::U128(val),
85            Content::I16(val) => Key::I64(val.into()),
86            Content::I32(val) => Key::I64(val.into()),
87            Content::I64(val) => Key::I64(val),
88            Content::I128(val) => Key::I128(val),
89            Content::F32(val) => Key::F64(val.into()),
90            Content::F64(val) => Key::F64(val),
91            Content::String(ref val) => Key::Str(val.as_str()),
92            Content::Bytes(ref val) => Key::Bytes(&val[..]),
93            _ => Key::Other,
94        }
95    }
96
97    pub(crate) fn sort_maps(&mut self) {
98        self.walk(&mut |content| {
99            if let Content::Map(ref mut items) = content {
100                // try to compare by key first, if that fails compare by the
101                // object value.  That way some values normalize, and if we
102                // can't normalize we still have a stable order.
103                items.sort_by(|a, b| match (a.0.as_key(), b.0.as_key()) {
104                    (Key::Other, _) | (_, Key::Other) => {
105                        a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal)
106                    }
107                    (ref a, ref b) => a.cmp(b),
108                })
109            }
110            true
111        })
112    }
113}
114
115#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
116impl Serialize for Content {
117    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
118    where
119        S: Serializer,
120    {
121        match *self {
122            Content::Bool(b) => serializer.serialize_bool(b),
123            Content::U8(u) => serializer.serialize_u8(u),
124            Content::U16(u) => serializer.serialize_u16(u),
125            Content::U32(u) => serializer.serialize_u32(u),
126            Content::U64(u) => serializer.serialize_u64(u),
127            Content::U128(u) => serializer.serialize_u128(u),
128            Content::I8(i) => serializer.serialize_i8(i),
129            Content::I16(i) => serializer.serialize_i16(i),
130            Content::I32(i) => serializer.serialize_i32(i),
131            Content::I64(i) => serializer.serialize_i64(i),
132            Content::I128(i) => serializer.serialize_i128(i),
133            Content::F32(f) => serializer.serialize_f32(f),
134            Content::F64(f) => serializer.serialize_f64(f),
135            Content::Char(c) => serializer.serialize_char(c),
136            Content::String(ref s) => serializer.serialize_str(s),
137            Content::Bytes(ref b) => serializer.serialize_bytes(b),
138            Content::None => serializer.serialize_none(),
139            Content::Some(ref c) => serializer.serialize_some(&**c),
140            Content::Unit => serializer.serialize_unit(),
141            Content::UnitStruct(n) => serializer.serialize_unit_struct(n),
142            Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v),
143            Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c),
144            Content::NewtypeVariant(n, i, v, ref c) => {
145                serializer.serialize_newtype_variant(n, i, v, &**c)
146            }
147            Content::Seq(ref elements) => elements.serialize(serializer),
148            Content::Tuple(ref elements) => {
149                use serde::ser::SerializeTuple;
150                let mut tuple = serializer.serialize_tuple(elements.len())?;
151                for e in elements {
152                    tuple.serialize_element(e)?;
153                }
154                tuple.end()
155            }
156            Content::TupleStruct(n, ref fields) => {
157                use serde::ser::SerializeTupleStruct;
158                let mut ts = serializer.serialize_tuple_struct(n, fields.len())?;
159                for f in fields {
160                    ts.serialize_field(f)?;
161                }
162                ts.end()
163            }
164            Content::TupleVariant(n, i, v, ref fields) => {
165                use serde::ser::SerializeTupleVariant;
166                let mut tv = serializer.serialize_tuple_variant(n, i, v, fields.len())?;
167                for f in fields {
168                    tv.serialize_field(f)?;
169                }
170                tv.end()
171            }
172            Content::Map(ref entries) => {
173                use serde::ser::SerializeMap;
174                let mut map = serializer.serialize_map(Some(entries.len()))?;
175                for (k, v) in entries {
176                    map.serialize_entry(k, v)?;
177                }
178                map.end()
179            }
180            Content::Struct(n, ref fields) => {
181                use serde::ser::SerializeStruct;
182                let mut s = serializer.serialize_struct(n, fields.len())?;
183                for &(k, ref v) in fields {
184                    s.serialize_field(k, v)?;
185                }
186                s.end()
187            }
188            Content::StructVariant(n, i, v, ref fields) => {
189                use serde::ser::SerializeStructVariant;
190                let mut sv = serializer.serialize_struct_variant(n, i, v, fields.len())?;
191                for &(k, ref v) in fields {
192                    sv.serialize_field(k, v)?;
193                }
194                sv.end()
195            }
196        }
197    }
198}
199
200pub struct ContentSerializer<E> {
201    error: PhantomData<E>,
202}
203
204impl<E> ContentSerializer<E> {
205    pub fn new() -> Self {
206        ContentSerializer { error: PhantomData }
207    }
208}
209
210impl<E> Serializer for ContentSerializer<E>
211where
212    E: ser::Error,
213{
214    type Ok = Content;
215    type Error = E;
216
217    type SerializeSeq = SerializeSeq<E>;
218    type SerializeTuple = SerializeTuple<E>;
219    type SerializeTupleStruct = SerializeTupleStruct<E>;
220    type SerializeTupleVariant = SerializeTupleVariant<E>;
221    type SerializeMap = SerializeMap<E>;
222    type SerializeStruct = SerializeStruct<E>;
223    type SerializeStructVariant = SerializeStructVariant<E>;
224
225    fn serialize_bool(self, v: bool) -> Result<Content, E> {
226        Ok(Content::Bool(v))
227    }
228
229    fn serialize_i8(self, v: i8) -> Result<Content, E> {
230        Ok(Content::I8(v))
231    }
232
233    fn serialize_i16(self, v: i16) -> Result<Content, E> {
234        Ok(Content::I16(v))
235    }
236
237    fn serialize_i32(self, v: i32) -> Result<Content, E> {
238        Ok(Content::I32(v))
239    }
240
241    fn serialize_i64(self, v: i64) -> Result<Content, E> {
242        Ok(Content::I64(v))
243    }
244
245    fn serialize_i128(self, v: i128) -> Result<Content, E> {
246        Ok(Content::I128(v))
247    }
248
249    fn serialize_u8(self, v: u8) -> Result<Content, E> {
250        Ok(Content::U8(v))
251    }
252
253    fn serialize_u16(self, v: u16) -> Result<Content, E> {
254        Ok(Content::U16(v))
255    }
256
257    fn serialize_u32(self, v: u32) -> Result<Content, E> {
258        Ok(Content::U32(v))
259    }
260
261    fn serialize_u64(self, v: u64) -> Result<Content, E> {
262        Ok(Content::U64(v))
263    }
264
265    fn serialize_u128(self, v: u128) -> Result<Content, E> {
266        Ok(Content::U128(v))
267    }
268
269    fn serialize_f32(self, v: f32) -> Result<Content, E> {
270        Ok(Content::F32(v))
271    }
272
273    fn serialize_f64(self, v: f64) -> Result<Content, E> {
274        Ok(Content::F64(v))
275    }
276
277    fn serialize_char(self, v: char) -> Result<Content, E> {
278        Ok(Content::Char(v))
279    }
280
281    fn serialize_str(self, value: &str) -> Result<Content, E> {
282        Ok(Content::String(value.to_owned()))
283    }
284
285    fn serialize_bytes(self, value: &[u8]) -> Result<Content, E> {
286        Ok(Content::Bytes(value.to_owned()))
287    }
288
289    fn serialize_none(self) -> Result<Content, E> {
290        Ok(Content::None)
291    }
292
293    fn serialize_some<T>(self, value: &T) -> Result<Content, E>
294    where
295        T: Serialize + ?Sized,
296    {
297        Ok(Content::Some(Box::new(value.serialize(self)?)))
298    }
299
300    fn serialize_unit(self) -> Result<Content, E> {
301        Ok(Content::Unit)
302    }
303
304    fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> {
305        Ok(Content::UnitStruct(name))
306    }
307
308    fn serialize_unit_variant(
309        self,
310        name: &'static str,
311        variant_index: u32,
312        variant: &'static str,
313    ) -> Result<Content, E> {
314        Ok(Content::UnitVariant(name, variant_index, variant))
315    }
316
317    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Content, E>
318    where
319        T: Serialize + ?Sized,
320    {
321        Ok(Content::NewtypeStruct(
322            name,
323            Box::new(value.serialize(self)?),
324        ))
325    }
326
327    fn serialize_newtype_variant<T>(
328        self,
329        name: &'static str,
330        variant_index: u32,
331        variant: &'static str,
332        value: &T,
333    ) -> Result<Content, E>
334    where
335        T: Serialize + ?Sized,
336    {
337        Ok(Content::NewtypeVariant(
338            name,
339            variant_index,
340            variant,
341            Box::new(value.serialize(self)?),
342        ))
343    }
344
345    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
346        Ok(SerializeSeq {
347            elements: Vec::with_capacity(len.unwrap_or(0)),
348            error: PhantomData,
349        })
350    }
351
352    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
353        Ok(SerializeTuple {
354            elements: Vec::with_capacity(len),
355            error: PhantomData,
356        })
357    }
358
359    fn serialize_tuple_struct(
360        self,
361        name: &'static str,
362        len: usize,
363    ) -> Result<Self::SerializeTupleStruct, E> {
364        Ok(SerializeTupleStruct {
365            name,
366            fields: Vec::with_capacity(len),
367            error: PhantomData,
368        })
369    }
370
371    fn serialize_tuple_variant(
372        self,
373        name: &'static str,
374        variant_index: u32,
375        variant: &'static str,
376        len: usize,
377    ) -> Result<Self::SerializeTupleVariant, E> {
378        Ok(SerializeTupleVariant {
379            name,
380            variant_index,
381            variant,
382            fields: Vec::with_capacity(len),
383            error: PhantomData,
384        })
385    }
386
387    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
388        Ok(SerializeMap {
389            entries: Vec::with_capacity(len.unwrap_or(0)),
390            key: None,
391            error: PhantomData,
392        })
393    }
394
395    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, E> {
396        Ok(SerializeStruct {
397            name,
398            fields: Vec::with_capacity(len),
399            error: PhantomData,
400        })
401    }
402
403    fn serialize_struct_variant(
404        self,
405        name: &'static str,
406        variant_index: u32,
407        variant: &'static str,
408        len: usize,
409    ) -> Result<Self::SerializeStructVariant, E> {
410        Ok(SerializeStructVariant {
411            name,
412            variant_index,
413            variant,
414            fields: Vec::with_capacity(len),
415            error: PhantomData,
416        })
417    }
418}
419
420pub struct SerializeSeq<E> {
421    elements: Vec<Content>,
422    error: PhantomData<E>,
423}
424
425impl<E> ser::SerializeSeq for SerializeSeq<E>
426where
427    E: ser::Error,
428{
429    type Ok = Content;
430    type Error = E;
431
432    fn serialize_element<T>(&mut self, value: &T) -> Result<(), E>
433    where
434        T: Serialize + ?Sized,
435    {
436        let value = value.serialize(ContentSerializer::<E>::new())?;
437        self.elements.push(value);
438        Ok(())
439    }
440
441    fn end(self) -> Result<Content, E> {
442        Ok(Content::Seq(self.elements))
443    }
444}
445
446pub struct SerializeTuple<E> {
447    elements: Vec<Content>,
448    error: PhantomData<E>,
449}
450
451impl<E> ser::SerializeTuple for SerializeTuple<E>
452where
453    E: ser::Error,
454{
455    type Ok = Content;
456    type Error = E;
457
458    fn serialize_element<T>(&mut self, value: &T) -> Result<(), E>
459    where
460        T: Serialize + ?Sized,
461    {
462        let value = value.serialize(ContentSerializer::<E>::new())?;
463        self.elements.push(value);
464        Ok(())
465    }
466
467    fn end(self) -> Result<Content, E> {
468        Ok(Content::Tuple(self.elements))
469    }
470}
471
472pub struct SerializeTupleStruct<E> {
473    name: &'static str,
474    fields: Vec<Content>,
475    error: PhantomData<E>,
476}
477
478impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
479where
480    E: ser::Error,
481{
482    type Ok = Content;
483    type Error = E;
484
485    fn serialize_field<T>(&mut self, value: &T) -> Result<(), E>
486    where
487        T: Serialize + ?Sized,
488    {
489        let value = value.serialize(ContentSerializer::<E>::new())?;
490        self.fields.push(value);
491        Ok(())
492    }
493
494    fn end(self) -> Result<Content, E> {
495        Ok(Content::TupleStruct(self.name, self.fields))
496    }
497}
498
499pub struct SerializeTupleVariant<E> {
500    name: &'static str,
501    variant_index: u32,
502    variant: &'static str,
503    fields: Vec<Content>,
504    error: PhantomData<E>,
505}
506
507impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
508where
509    E: ser::Error,
510{
511    type Ok = Content;
512    type Error = E;
513
514    fn serialize_field<T>(&mut self, value: &T) -> Result<(), E>
515    where
516        T: Serialize + ?Sized,
517    {
518        let value = value.serialize(ContentSerializer::<E>::new())?;
519        self.fields.push(value);
520        Ok(())
521    }
522
523    fn end(self) -> Result<Content, E> {
524        Ok(Content::TupleVariant(
525            self.name,
526            self.variant_index,
527            self.variant,
528            self.fields,
529        ))
530    }
531}
532
533pub struct SerializeMap<E> {
534    entries: Vec<(Content, Content)>,
535    key: Option<Content>,
536    error: PhantomData<E>,
537}
538
539impl<E> ser::SerializeMap for SerializeMap<E>
540where
541    E: ser::Error,
542{
543    type Ok = Content;
544    type Error = E;
545
546    fn serialize_key<T>(&mut self, key: &T) -> Result<(), E>
547    where
548        T: Serialize + ?Sized,
549    {
550        let key = key.serialize(ContentSerializer::<E>::new())?;
551        self.key = Some(key);
552        Ok(())
553    }
554
555    fn serialize_value<T>(&mut self, value: &T) -> Result<(), E>
556    where
557        T: Serialize + ?Sized,
558    {
559        let key = self
560            .key
561            .take()
562            .expect("serialize_value called before serialize_key");
563        let value = value.serialize(ContentSerializer::<E>::new())?;
564        self.entries.push((key, value));
565        Ok(())
566    }
567
568    fn end(self) -> Result<Content, E> {
569        Ok(Content::Map(self.entries))
570    }
571
572    fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), E>
573    where
574        K: Serialize + ?Sized,
575        V: Serialize + ?Sized,
576    {
577        let key = key.serialize(ContentSerializer::<E>::new())?;
578        let value = value.serialize(ContentSerializer::<E>::new())?;
579        self.entries.push((key, value));
580        Ok(())
581    }
582}
583
584pub struct SerializeStruct<E> {
585    name: &'static str,
586    fields: Vec<(&'static str, Content)>,
587    error: PhantomData<E>,
588}
589
590impl<E> ser::SerializeStruct for SerializeStruct<E>
591where
592    E: ser::Error,
593{
594    type Ok = Content;
595    type Error = E;
596
597    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), E>
598    where
599        T: Serialize + ?Sized,
600    {
601        let value = value.serialize(ContentSerializer::<E>::new())?;
602        self.fields.push((key, value));
603        Ok(())
604    }
605
606    fn end(self) -> Result<Content, E> {
607        Ok(Content::Struct(self.name, self.fields))
608    }
609}
610
611pub struct SerializeStructVariant<E> {
612    name: &'static str,
613    variant_index: u32,
614    variant: &'static str,
615    fields: Vec<(&'static str, Content)>,
616    error: PhantomData<E>,
617}
618
619impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
620where
621    E: ser::Error,
622{
623    type Ok = Content;
624    type Error = E;
625
626    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), E>
627    where
628        T: Serialize + ?Sized,
629    {
630        let value = value.serialize(ContentSerializer::<E>::new())?;
631        self.fields.push((key, value));
632        Ok(())
633    }
634
635    fn end(self) -> Result<Content, E> {
636        Ok(Content::StructVariant(
637            self.name,
638            self.variant_index,
639            self.variant,
640            self.fields,
641        ))
642    }
643}