miniserde 0.1.45

Data structure serialization library with several opposite design goals from Serde.
Documentation
use crate::private;
use crate::ser::{Fragment, Map, Seq, Serialize};
use alloc::borrow::{Cow, ToOwned};
use alloc::boxed::Box;
use alloc::collections::{btree_map, BTreeMap};
use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::slice;
use core::str;
#[cfg(feature = "std")]
use std::collections::{hash_map, HashMap};
#[cfg(feature = "std")]
use std::hash::{BuildHasher, Hash};

impl Serialize for () {
    fn begin(&self) -> Fragment {
        Fragment::Null
    }
}

impl Serialize for bool {
    fn begin(&self) -> Fragment {
        Fragment::Bool(*self)
    }
}

impl Serialize for str {
    fn begin(&self) -> Fragment {
        Fragment::Str(Cow::Borrowed(self))
    }
}

impl Serialize for String {
    fn begin(&self) -> Fragment {
        Fragment::Str(Cow::Borrowed(self))
    }
}

macro_rules! unsigned {
    ($ty:ident) => {
        impl Serialize for $ty {
            fn begin(&self) -> Fragment {
                Fragment::U64(*self as u64)
            }
        }
    };
}
unsigned!(u8);
unsigned!(u16);
unsigned!(u32);
unsigned!(u64);
unsigned!(usize);

macro_rules! signed {
    ($ty:ident) => {
        impl Serialize for $ty {
            fn begin(&self) -> Fragment {
                Fragment::I64(*self as i64)
            }
        }
    };
}
signed!(i8);
signed!(i16);
signed!(i32);
signed!(i64);
signed!(isize);

macro_rules! float {
    ($ty:ident) => {
        impl Serialize for $ty {
            fn begin(&self) -> Fragment {
                Fragment::F64(*self as f64)
            }
        }
    };
}
float!(f32);
float!(f64);

impl<T> Serialize for &T
where
    T: ?Sized + Serialize,
{
    fn begin(&self) -> Fragment {
        (**self).begin()
    }
}

impl<T> Serialize for Box<T>
where
    T: ?Sized + Serialize,
{
    fn begin(&self) -> Fragment {
        (**self).begin()
    }
}

impl<T> Serialize for Option<T>
where
    T: Serialize,
{
    fn begin(&self) -> Fragment {
        match self {
            Some(some) => some.begin(),
            None => Fragment::Null,
        }
    }
}

impl<'a, T> Serialize for Cow<'a, T>
where
    T: ?Sized + ToOwned + Serialize,
{
    fn begin(&self) -> Fragment {
        (**self).begin()
    }
}

impl<A, B> Serialize for (A, B)
where
    A: Serialize,
    B: Serialize,
{
    fn begin(&self) -> Fragment {
        struct TupleStream<'a> {
            first: &'a dyn Serialize,
            second: &'a dyn Serialize,
            state: usize,
        }

        impl<'a> Seq for TupleStream<'a> {
            fn next(&mut self) -> Option<&dyn Serialize> {
                let state = self.state;
                self.state += 1;
                match state {
                    0 => Some(self.first),
                    1 => Some(self.second),
                    _ => None,
                }
            }
        }

        Fragment::Seq(Box::new(TupleStream {
            first: &self.0,
            second: &self.1,
            state: 0,
        }))
    }
}

impl<T> Serialize for [T]
where
    T: Serialize,
{
    fn begin(&self) -> Fragment {
        private::stream_slice(self)
    }
}

impl<T, const N: usize> Serialize for [T; N]
where
    T: Serialize,
{
    fn begin(&self) -> Fragment {
        private::stream_slice(self)
    }
}

impl<T> Serialize for Vec<T>
where
    T: Serialize,
{
    fn begin(&self) -> Fragment {
        private::stream_slice(self)
    }
}

#[cfg(feature = "std")]
impl<K, V, H> Serialize for HashMap<K, V, H>
where
    K: Hash + Eq + ToString,
    V: Serialize,
    H: BuildHasher,
{
    fn begin(&self) -> Fragment {
        struct HashMapStream<'a, K: 'a, V: 'a>(hash_map::Iter<'a, K, V>);

        impl<'a, K, V> Map for HashMapStream<'a, K, V>
        where
            K: ToString,
            V: Serialize,
        {
            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
                let (k, v) = self.0.next()?;
                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
            }
        }

        Fragment::Map(Box::new(HashMapStream(self.iter())))
    }
}

impl<K, V> Serialize for BTreeMap<K, V>
where
    K: ToString,
    V: Serialize,
{
    fn begin(&self) -> Fragment {
        private::stream_btree_map(self)
    }
}

impl private {
    pub fn stream_slice<T>(slice: &[T]) -> Fragment
    where
        T: Serialize,
    {
        struct SliceStream<'a, T: 'a>(slice::Iter<'a, T>);

        impl<'a, T> Seq for SliceStream<'a, T>
        where
            T: Serialize,
        {
            fn next(&mut self) -> Option<&dyn Serialize> {
                let element = self.0.next()?;
                Some(element)
            }
        }

        Fragment::Seq(Box::new(SliceStream(slice.iter())))
    }

    pub fn stream_btree_map<K, V>(map: &BTreeMap<K, V>) -> Fragment
    where
        K: ToString,
        V: Serialize,
    {
        struct BTreeMapStream<'a, K, V>(btree_map::Iter<'a, K, V>)
        where
            K: 'a,
            V: 'a;

        impl<'a, K, V> Map for BTreeMapStream<'a, K, V>
        where
            K: ToString,
            V: Serialize,
        {
            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
                let (k, v) = self.0.next()?;
                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
            }
        }

        Fragment::Map(Box::new(BTreeMapStream(map.iter())))
    }
}