Skip to main content

deser_value/
ser.rs

1use deser_core::Text;
2use deser_core::ser::{Chunk, MapEmitter, SeqEmitter, Serialize, SerializeHandle};
3use deser_core::{Atom, ContainerShape, Error, ErrorKind, State};
4
5use crate::map::Map;
6use crate::seq::Seq;
7use crate::value::{Kind, Value};
8
9impl Serialize for Value {
10    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
11        if let Some(ref meta) = self.meta
12            && !meta.event_data().is_empty()
13        {
14            state.attach_event_data(meta.event_data());
15        }
16        self.kind.serialize(state)
17    }
18
19    fn container_shape(&self) -> ContainerShape {
20        self.kind.container_shape()
21    }
22
23    fn is_optional(&self) -> bool {
24        matches!(self.kind, Kind::Null)
25    }
26}
27
28impl Serialize for Kind {
29    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
30        Ok(match self {
31            Kind::Null => Chunk::Atom(Atom::Null),
32            Kind::Bool(value) => Chunk::Atom(Atom::Bool(*value)),
33            Kind::U64(value) => Chunk::Atom(Atom::U64(*value)),
34            Kind::I64(value) => Chunk::Atom(Atom::I64(*value)),
35            Kind::F32(value) => Chunk::Atom(Atom::F32(*value)),
36            Kind::F64(value) => Chunk::Atom(Atom::F64(*value)),
37            Kind::Char(value) => Chunk::Atom(Atom::Char(*value)),
38            Kind::Str(value) => Chunk::Atom(Atom::Str(Text::borrowed(value))),
39            Kind::Lexical(value) => Chunk::Atom(Atom::Lexical(Text::borrowed(value))),
40            Kind::Bytes(value) => Chunk::Atom(Atom::Bytes(value.as_borrowed())),
41            Kind::Ext(value) => Chunk::Atom(Atom::Ext(value.as_borrowed())),
42            Kind::Implicit(value) => Chunk::Atom(Atom::Implicit(value.as_borrowed())),
43            Kind::Seq(seq) => return seq.serialize(state),
44            Kind::Map(map) => return map.serialize(state),
45        })
46    }
47
48    fn container_shape(&self) -> ContainerShape {
49        match self {
50            Kind::Seq(seq) => seq.container_shape(),
51            Kind::Map(map) => map.container_shape(),
52            _ => ContainerShape::new(),
53        }
54    }
55
56    fn is_optional(&self) -> bool {
57        matches!(self, Kind::Null)
58    }
59}
60
61impl Serialize for Seq {
62    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
63        Ok(Chunk::seq(SeqIter(self.items.iter()), state))
64    }
65
66    fn container_shape(&self) -> ContainerShape {
67        ContainerShape::new()
68            .with_len(self.len())
69            .with_order(self.order())
70    }
71}
72
73struct SeqIter<'a>(std::slice::Iter<'a, Value>);
74
75impl SeqEmitter for SeqIter<'_> {
76    fn next(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
77        Ok(self.0.next().map(SerializeHandle::to))
78    }
79}
80
81impl Serialize for Map {
82    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
83        Ok(Chunk::map(
84            MapIter {
85                iter: self.inner.entries.iter(),
86                value: None,
87            },
88            state,
89        ))
90    }
91
92    fn container_shape(&self) -> ContainerShape {
93        ContainerShape::new()
94            .with_len(self.len())
95            .with_order(self.order())
96            .with_multimap(self.is_multimap())
97    }
98}
99
100struct MapIter<'a> {
101    iter: indexmap::map::Iter<'a, Value, Value>,
102    value: Option<&'a Value>,
103}
104
105impl MapEmitter for MapIter<'_> {
106    fn next_key(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
107        Ok(self.iter.next().map(|(key, value)| {
108            self.value = Some(value);
109            SerializeHandle::to(key)
110        }))
111    }
112
113    fn next_value(&mut self, _state: &mut State) -> Result<SerializeHandle<'_>, Error> {
114        match self.value.take() {
115            Some(value) => Ok(SerializeHandle::to(value)),
116            None => Err(Error::new(
117                ErrorKind::Unexpected,
118                "next_value called before next_key",
119            )),
120        }
121    }
122}