miniserde_miku/ser/
impls.rs1use 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}