merde_core/
serialize.rs

1use std::{
2    borrow::Cow, collections::HashMap, future::Future, hash::BuildHasher, pin::Pin, sync::Arc,
3};
4
5use crate::{
6    metastack::MetastackExt, Array, ArrayStart, CowBytes, CowStr, Event, Map, MapStart, MerdeError,
7    Value,
8};
9
10pub trait Serializer {
11    fn write<'fut>(
12        &'fut mut self,
13        ev: Event<'fut>,
14    ) -> impl Future<Output = Result<(), MerdeError<'static>>> + 'fut;
15}
16
17type BoxFut<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
18
19pub trait DynSerializer {
20    fn write<'fut>(
21        &'fut mut self,
22        ev: Event<'fut>,
23    ) -> BoxFut<'fut, Result<(), MerdeError<'static>>>;
24}
25
26impl dyn DynSerializer {
27    fn _assert_dyn_safe(_: Box<dyn DynSerializer>) {}
28}
29
30impl<S> DynSerializer for S
31where
32    S: Serializer,
33{
34    fn write<'fut>(
35        &'fut mut self,
36        ev: Event<'fut>,
37    ) -> BoxFut<'fut, Result<(), MerdeError<'static>>> {
38        Box::pin(Serializer::write(self, ev))
39    }
40}
41
42pub trait DynSerializerExt {
43    fn serialize<T: Serialize>(&mut self, t: &T) -> Result<(), MerdeError<'static>>;
44    fn dyn_serialize(&mut self, t: &dyn DynSerialize) -> Result<(), MerdeError<'static>>;
45}
46
47impl<S> DynSerializerExt for S
48where
49    S: DynSerializer,
50{
51    fn serialize<T: Serialize>(&mut self, t: &T) -> Result<(), MerdeError<'static>> {
52        T::serialize(t, self).run_sync_with_metastack()
53    }
54
55    fn dyn_serialize(&mut self, t: &dyn DynSerialize) -> Result<(), MerdeError<'static>> {
56        DynSerialize::dyn_serialize(t, self).run_sync_with_metastack()
57    }
58}
59
60pub trait Serialize {
61    fn serialize<'fut>(
62        &'fut self,
63        serializer: &'fut mut dyn DynSerializer,
64    ) -> impl Future<Output = Result<(), MerdeError<'static>>> + 'fut;
65}
66
67/// Dynamic dispatch version of [`Serialize`].
68pub trait DynSerialize {
69    /// Dynamic dispatch version of [`Serialize::serialize`].
70    fn dyn_serialize<'fut>(
71        &'fut self,
72        serializer: &'fut mut dyn DynSerializer,
73    ) -> BoxFut<'fut, Result<(), MerdeError<'static>>>;
74}
75
76impl<S> DynSerialize for S
77where
78    S: Serialize,
79{
80    fn dyn_serialize<'fut>(
81        &'fut self,
82        serializer: &'fut mut dyn DynSerializer,
83    ) -> BoxFut<'fut, Result<(), MerdeError<'static>>> {
84        Box::pin(Serialize::serialize(self, serializer))
85    }
86}
87
88macro_rules! impl_trivial_serialize {
89    ($ty:ty, $($rest:tt)*) => {
90        impl_trivial_serialize!($ty);
91        impl_trivial_serialize!($($rest)*);
92    };
93
94    ($ty:ty) => {
95        impl Serialize for $ty {
96            async fn serialize<'fut>(
97                &'fut self,
98                serializer: &'fut mut dyn DynSerializer,
99            ) -> Result<(), MerdeError<'static>> {
100                serializer.write(Event::from(*self)).await
101            }
102        }
103    };
104
105    (,) => {};
106    () => {};
107}
108
109impl_trivial_serialize! {
110    i8, i16, i32, i64,
111    u8, u16, u32, u64,
112    isize, usize,
113    // floats
114    f32, f64,
115    // misc.
116    bool,
117}
118
119#[cfg(feature = "camino")]
120impl Serialize for camino::Utf8PathBuf {
121    async fn serialize<'se>(
122        &'se self,
123        serializer: &'se mut dyn DynSerializer,
124    ) -> Result<(), MerdeError<'static>> {
125        use crate::CowStr;
126        serializer
127            .write(Event::Str(CowStr::Borrowed(self.as_str())))
128            .await
129    }
130}
131
132impl Serialize for String {
133    async fn serialize<'se>(
134        &'se self,
135        serializer: &'se mut dyn DynSerializer,
136    ) -> Result<(), MerdeError<'static>> {
137        serializer.write(Event::Str(CowStr::Borrowed(self))).await
138    }
139}
140
141impl<'s> Serialize for &'s str {
142    async fn serialize<'se>(
143        &'se self,
144        serializer: &'se mut dyn DynSerializer,
145    ) -> Result<(), MerdeError<'static>> {
146        serializer.write(Event::Str(CowStr::Borrowed(self))).await
147    }
148}
149
150impl<'s> Serialize for CowStr<'s> {
151    async fn serialize<'se>(
152        &'se self,
153        serializer: &'se mut dyn DynSerializer,
154    ) -> Result<(), MerdeError<'static>> {
155        serializer
156            .write(Event::Str(CowStr::Borrowed(self.as_ref())))
157            .await
158    }
159}
160
161impl<'s> Serialize for Cow<'s, str> {
162    async fn serialize<'se>(
163        &'se self,
164        serializer: &'se mut dyn DynSerializer,
165    ) -> Result<(), MerdeError<'static>> {
166        serializer
167            .write(Event::Str(CowStr::Borrowed(self.as_ref())))
168            .await
169    }
170}
171
172impl<'s> Serialize for CowBytes<'s> {
173    async fn serialize<'se>(
174        &'se self,
175        serializer: &'se mut dyn DynSerializer,
176    ) -> Result<(), MerdeError<'static>> {
177        serializer
178            .write(Event::Bytes(CowBytes::Borrowed(self.as_ref())))
179            .await
180    }
181}
182
183impl<T: Serialize> Serialize for Option<T> {
184    async fn serialize<'se>(
185        &'se self,
186        serializer: &'se mut dyn DynSerializer,
187    ) -> Result<(), MerdeError<'static>> {
188        match self {
189            Some(value) => value.serialize(serializer).await,
190            None => serializer.write(Event::Null).await,
191        }
192    }
193}
194
195impl<T: Serialize> Serialize for &[T] {
196    async fn serialize<'se>(
197        &'se self,
198        serializer: &'se mut dyn DynSerializer,
199    ) -> Result<(), MerdeError<'static>> {
200        serializer
201            .write(Event::ArrayStart(ArrayStart {
202                size_hint: Some(self.len()),
203            }))
204            .await?;
205        for item in *self {
206            item.serialize(serializer).await?;
207        }
208        serializer.write(Event::ArrayEnd).await
209    }
210}
211
212impl<T: Serialize> Serialize for Vec<T> {
213    async fn serialize<'se>(
214        &'se self,
215        serializer: &'se mut dyn DynSerializer,
216    ) -> Result<(), MerdeError<'static>> {
217        serializer
218            .write(Event::ArrayStart(ArrayStart {
219                size_hint: Some(self.len()),
220            }))
221            .await?;
222        for item in self {
223            item.serialize(serializer).await?;
224        }
225        serializer.write(Event::ArrayEnd).await
226    }
227}
228
229impl<T: Serialize> Serialize for Box<T> {
230    async fn serialize<'se>(
231        &'se self,
232        serializer: &'se mut dyn DynSerializer,
233    ) -> Result<(), MerdeError<'static>> {
234        (**self).serialize(serializer).await
235    }
236}
237
238impl<T: Serialize> Serialize for Arc<T> {
239    async fn serialize<'se>(
240        &'se self,
241        serializer: &'se mut dyn DynSerializer,
242    ) -> Result<(), MerdeError<'static>> {
243        (**self).serialize(serializer).await
244    }
245}
246
247impl<K: Serialize, V: Serialize, BH: BuildHasher> Serialize for HashMap<K, V, BH> {
248    async fn serialize<'fut>(
249        &'fut self,
250        serializer: &'fut mut dyn DynSerializer,
251    ) -> Result<(), MerdeError<'static>> {
252        serializer
253            .write(Event::MapStart(MapStart {
254                size_hint: Some(self.len()),
255            }))
256            .await?;
257        for (key, value) in self {
258            key.serialize(serializer).await?;
259            value.serialize(serializer).await?;
260        }
261        serializer.write(Event::MapEnd).await
262    }
263}
264
265impl Serialize for Map<'_> {
266    async fn serialize<'se>(
267        &'se self,
268        serializer: &'se mut dyn DynSerializer,
269    ) -> Result<(), MerdeError<'static>> {
270        serializer
271            .write(Event::MapStart(MapStart {
272                size_hint: Some(self.len()),
273            }))
274            .await?;
275        for (key, value) in self.iter() {
276            serializer.write(Event::Str(CowStr::Borrowed(key))).await?;
277            value.serialize(serializer).await?;
278        }
279        serializer.write(Event::MapEnd).await
280    }
281}
282
283impl Serialize for Array<'_> {
284    async fn serialize<'se>(
285        &'se self,
286        serializer: &'se mut dyn DynSerializer,
287    ) -> Result<(), MerdeError<'static>> {
288        serializer
289            .write(Event::ArrayStart(ArrayStart {
290                size_hint: Some(self.len()),
291            }))
292            .await?;
293        for item in self.iter() {
294            item.serialize(serializer).await?;
295        }
296        serializer.write(Event::ArrayEnd).await
297    }
298}
299
300impl Serialize for Value<'_> {
301    async fn serialize<'se>(
302        &'se self,
303        serializer: &'se mut dyn DynSerializer,
304    ) -> Result<(), MerdeError<'static>> {
305        match self {
306            Value::I64(i) => serializer.write(Event::I64(*i)).await,
307            Value::U64(u) => serializer.write(Event::U64(*u)).await,
308            Value::Float(f) => serializer.write(Event::F64(f.into_inner())).await,
309            Value::Str(s) => serializer.write(Event::Str(s.clone())).await,
310            Value::Bytes(b) => serializer.write(Event::Bytes(b.clone())).await,
311            Value::Null => serializer.write(Event::Null).await,
312            Value::Bool(b) => serializer.write(Event::Bool(*b)).await,
313            Value::Array(arr) => {
314                arr.serialize(serializer)
315                    .with_metastack_resume_point()
316                    .await
317            }
318            Value::Map(map) => {
319                map.serialize(serializer)
320                    .with_metastack_resume_point()
321                    .await
322            }
323        }
324    }
325}
326
327macro_rules! impl_serialize_for_tuple {
328    ($($type_arg:ident),*) => {
329        impl<$($type_arg: Serialize),*> Serialize for ($($type_arg),*,) {
330            async fn serialize<'se>(
331                &'se self,
332                serializer: &'se mut dyn DynSerializer,
333            ) -> Result<(), MerdeError<'static>> {
334                serializer.write(Event::ArrayStart(ArrayStart {
335                    size_hint: Some(count_tup!($($type_arg)*))
336                })).await?;
337
338                impl_serialize_for_tuple!(@inner self serializer _field => _field () ($($type_arg)*));
339                serializer.write(Event::ArrayEnd).await
340            }
341        }
342    };
343
344    (@inner $self:ident $serializer:ident $fieldpat:pat => $field:ident ($($ignores:tt)*) ($x:ident $($xs:ident)*)) => {
345        let ($($ignores)* $fieldpat, ..) = &$self;
346        $field.serialize($serializer).await?;
347        impl_serialize_for_tuple!(@inner $self $serializer $fieldpat => $field ($($ignores)* _,) ($($xs)*));
348    };
349    (@inner $self:ident $serializer:ident $fieldpat:pat => $field:ident ($($ignores:tt)*) ()) => {
350        // we're done
351    }
352}
353
354macro_rules! count_tup {
355    () => { 0 };
356    ($t:ident $($rest:ident)*) => { 1 + count_tup!($($rest)*) };
357}
358
359impl_serialize_for_tuple!(T0);
360impl_serialize_for_tuple!(T0, T1);
361impl_serialize_for_tuple!(T0, T1, T2);
362impl_serialize_for_tuple!(T0, T1, T2, T3);
363impl_serialize_for_tuple!(T0, T1, T2, T3, T4);
364impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5);
365impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6);
366impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7);
367impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
368impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
369impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
370impl_serialize_for_tuple!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
371
372#[cfg(test)]
373mod tests;