miniserde/ser/
impls.rs

1use crate::private;
2use crate::ser::{Fragment, Map, Seq, Serialize};
3use alloc::borrow::{Cow, ToOwned};
4use alloc::boxed::Box;
5use alloc::collections::{btree_map, BTreeMap};
6use alloc::string::{String, ToString};
7use alloc::vec::Vec;
8use core::slice;
9use core::str;
10#[cfg(feature = "std")]
11use std::collections::{hash_map, HashMap};
12#[cfg(feature = "std")]
13use std::hash::{BuildHasher, Hash};
14
15impl Serialize for () {
16    fn begin(&self) -> Fragment {
17        Fragment::Null
18    }
19}
20
21impl Serialize for bool {
22    fn begin(&self) -> Fragment {
23        Fragment::Bool(*self)
24    }
25}
26
27impl Serialize for str {
28    fn begin(&self) -> Fragment {
29        Fragment::Str(Cow::Borrowed(self))
30    }
31}
32
33impl Serialize for String {
34    fn begin(&self) -> Fragment {
35        Fragment::Str(Cow::Borrowed(self))
36    }
37}
38
39macro_rules! unsigned {
40    ($ty:ident) => {
41        impl Serialize for $ty {
42            fn begin(&self) -> Fragment {
43                Fragment::U64(*self as u64)
44            }
45        }
46    };
47}
48unsigned!(u8);
49unsigned!(u16);
50unsigned!(u32);
51unsigned!(u64);
52unsigned!(usize);
53
54macro_rules! signed {
55    ($ty:ident) => {
56        impl Serialize for $ty {
57            fn begin(&self) -> Fragment {
58                Fragment::I64(*self as i64)
59            }
60        }
61    };
62}
63signed!(i8);
64signed!(i16);
65signed!(i32);
66signed!(i64);
67signed!(isize);
68
69macro_rules! float {
70    ($ty:ident) => {
71        impl Serialize for $ty {
72            fn begin(&self) -> Fragment {
73                Fragment::F64(*self as f64)
74            }
75        }
76    };
77}
78float!(f32);
79float!(f64);
80
81impl<T> Serialize for &T
82where
83    T: ?Sized + Serialize,
84{
85    fn begin(&self) -> Fragment {
86        (**self).begin()
87    }
88}
89
90impl<T> Serialize for Box<T>
91where
92    T: ?Sized + Serialize,
93{
94    fn begin(&self) -> Fragment {
95        (**self).begin()
96    }
97}
98
99impl<T> Serialize for Option<T>
100where
101    T: Serialize,
102{
103    fn begin(&self) -> Fragment {
104        match self {
105            Some(some) => some.begin(),
106            None => Fragment::Null,
107        }
108    }
109}
110
111impl<'a, T> Serialize for Cow<'a, T>
112where
113    T: ?Sized + ToOwned + Serialize,
114{
115    fn begin(&self) -> Fragment {
116        (**self).begin()
117    }
118}
119
120impl<A, B> Serialize for (A, B)
121where
122    A: Serialize,
123    B: Serialize,
124{
125    fn begin(&self) -> Fragment {
126        struct TupleStream<'a> {
127            first: &'a dyn Serialize,
128            second: &'a dyn Serialize,
129            state: usize,
130        }
131
132        impl<'a> Seq for TupleStream<'a> {
133            fn next(&mut self) -> Option<&dyn Serialize> {
134                let state = self.state;
135                self.state += 1;
136                match state {
137                    0 => Some(self.first),
138                    1 => Some(self.second),
139                    _ => None,
140                }
141            }
142        }
143
144        Fragment::Seq(Box::new(TupleStream {
145            first: &self.0,
146            second: &self.1,
147            state: 0,
148        }))
149    }
150}
151
152impl<T> Serialize for [T]
153where
154    T: Serialize,
155{
156    fn begin(&self) -> Fragment {
157        private::stream_slice(self)
158    }
159}
160
161impl<T, const N: usize> Serialize for [T; N]
162where
163    T: Serialize,
164{
165    fn begin(&self) -> Fragment {
166        private::stream_slice(self)
167    }
168}
169
170impl<T> Serialize for Vec<T>
171where
172    T: Serialize,
173{
174    fn begin(&self) -> Fragment {
175        private::stream_slice(self)
176    }
177}
178
179#[cfg(feature = "std")]
180impl<K, V, H> Serialize for HashMap<K, V, H>
181where
182    K: Hash + Eq + ToString,
183    V: Serialize,
184    H: BuildHasher,
185{
186    fn begin(&self) -> Fragment {
187        struct HashMapStream<'a, K: 'a, V: 'a>(hash_map::Iter<'a, K, V>);
188
189        impl<'a, K, V> Map for HashMapStream<'a, K, V>
190        where
191            K: ToString,
192            V: Serialize,
193        {
194            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
195                let (k, v) = self.0.next()?;
196                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
197            }
198        }
199
200        Fragment::Map(Box::new(HashMapStream(self.iter())))
201    }
202}
203
204impl<K, V> Serialize for BTreeMap<K, V>
205where
206    K: ToString,
207    V: Serialize,
208{
209    fn begin(&self) -> Fragment {
210        private::stream_btree_map(self)
211    }
212}
213
214impl private {
215    pub fn stream_slice<T>(slice: &[T]) -> Fragment
216    where
217        T: Serialize,
218    {
219        struct SliceStream<'a, T: 'a>(slice::Iter<'a, T>);
220
221        impl<'a, T> Seq for SliceStream<'a, T>
222        where
223            T: Serialize,
224        {
225            fn next(&mut self) -> Option<&dyn Serialize> {
226                let element = self.0.next()?;
227                Some(element)
228            }
229        }
230
231        Fragment::Seq(Box::new(SliceStream(slice.iter())))
232    }
233
234    pub fn stream_btree_map<K, V>(map: &BTreeMap<K, V>) -> Fragment
235    where
236        K: ToString,
237        V: Serialize,
238    {
239        struct BTreeMapStream<'a, K, V>(btree_map::Iter<'a, K, V>)
240        where
241            K: 'a,
242            V: 'a;
243
244        impl<'a, K, V> Map for BTreeMapStream<'a, K, V>
245        where
246            K: ToString,
247            V: Serialize,
248        {
249            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
250                let (k, v) = self.0.next()?;
251                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
252            }
253        }
254
255        Fragment::Map(Box::new(BTreeMapStream(map.iter())))
256    }
257}