Skip to main content

miniserde_miku/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<'a, T: ?Sized + Serialize> Serialize for &'a T {
82    fn begin(&self) -> Fragment {
83        (**self).begin()
84    }
85}
86
87impl<T: ?Sized + Serialize> Serialize for Box<T> {
88    fn begin(&self) -> Fragment {
89        (**self).begin()
90    }
91}
92
93impl<T: Serialize> Serialize for Option<T> {
94    fn begin(&self) -> Fragment {
95        match self {
96            Some(some) => some.begin(),
97            None => Fragment::Null,
98        }
99    }
100}
101
102impl<'a, T: ?Sized + ToOwned + Serialize> Serialize for Cow<'a, T> {
103    fn begin(&self) -> Fragment {
104        (**self).begin()
105    }
106}
107
108impl<A: Serialize, B: Serialize> Serialize for (A, B) {
109    fn begin(&self) -> Fragment {
110        struct TupleStream<'a> {
111            first: &'a dyn Serialize,
112            second: &'a dyn Serialize,
113            state: usize,
114        }
115
116        impl<'a> Seq for TupleStream<'a> {
117            fn next(&mut self) -> Option<&dyn Serialize> {
118                let state = self.state;
119                self.state += 1;
120                match state {
121                    0 => Some(self.first),
122                    1 => Some(self.second),
123                    _ => None,
124                }
125            }
126        }
127
128        Fragment::Seq(Box::new(TupleStream {
129            first: &self.0,
130            second: &self.1,
131            state: 0,
132        }))
133    }
134}
135
136impl<T: Serialize> Serialize for [T] {
137    fn begin(&self) -> Fragment {
138        private::stream_slice(self)
139    }
140}
141
142impl<T: Serialize> Serialize for Vec<T> {
143    fn begin(&self) -> Fragment {
144        private::stream_slice(self)
145    }
146}
147
148#[cfg(feature = "std")]
149impl<K, V, H> Serialize for HashMap<K, V, H>
150where
151    K: Hash + Eq + ToString,
152    V: Serialize,
153    H: BuildHasher,
154{
155    fn begin(&self) -> Fragment {
156        struct HashMapStream<'a, K: 'a, V: 'a>(hash_map::Iter<'a, K, V>);
157
158        impl<'a, K: ToString, V: Serialize> Map for HashMapStream<'a, K, V> {
159            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
160                let (k, v) = self.0.next()?;
161                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
162            }
163        }
164
165        Fragment::Map(Box::new(HashMapStream(self.iter())))
166    }
167}
168
169impl<K: ToString, V: Serialize> Serialize for BTreeMap<K, V> {
170    fn begin(&self) -> Fragment {
171        private::stream_btree_map(self)
172    }
173}
174
175impl private {
176    pub fn stream_slice<T: Serialize>(slice: &[T]) -> Fragment {
177        struct SliceStream<'a, T: 'a>(slice::Iter<'a, T>);
178
179        impl<'a, T: Serialize> Seq for SliceStream<'a, T> {
180            fn next(&mut self) -> Option<&dyn Serialize> {
181                let element = self.0.next()?;
182                Some(element)
183            }
184        }
185
186        Fragment::Seq(Box::new(SliceStream(slice.iter())))
187    }
188
189    pub fn stream_btree_map<K: ToString, V: Serialize>(map: &BTreeMap<K, V>) -> Fragment {
190        struct BTreeMapStream<'a, K: 'a, V: 'a>(btree_map::Iter<'a, K, V>);
191
192        impl<'a, K: ToString, V: Serialize> Map for BTreeMapStream<'a, K, V> {
193            fn next(&mut self) -> Option<(Cow<str>, &dyn Serialize)> {
194                let (k, v) = self.0.next()?;
195                Some((Cow::Owned(k.to_string()), v as &dyn Serialize))
196            }
197        }
198
199        Fragment::Map(Box::new(BTreeMapStream(map.iter())))
200    }
201}