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}