deser_path/
ser.rs

1use std::borrow::Cow;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use deser::ser::{
6    Chunk, MapEmitter, SeqEmitter, Serialize, SerializeHandle, SerializerState, StructEmitter,
7};
8use deser::{Atom, Error};
9
10use crate::{Path, PathSegment};
11
12/// Wraps a serializable so that it tracks the current path.
13pub struct PathSerializable<'a> {
14    serializable: SerializeHandle<'a>,
15}
16
17impl<'a> PathSerializable<'a> {
18    /// Wraps another serializable.
19    pub fn wrap(serializable: &'a dyn Serialize) -> PathSerializable<'a> {
20        PathSerializable::wrap_ref(SerializeHandle::Borrowed(serializable))
21    }
22
23    /// Wraps another serializable ref.
24    pub fn wrap_ref(serializable: SerializeHandle<'a>) -> PathSerializable<'a> {
25        PathSerializable { serializable }
26    }
27}
28
29impl<'a> Serialize for PathSerializable<'a> {
30    fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
31        match self.serializable.serialize(state)? {
32            Chunk::Struct(emitter) => Ok(Chunk::Struct(Box::new(PathStructEmitter { emitter }))),
33            Chunk::Map(emitter) => Ok(Chunk::Map(Box::new(PathMapEmitter {
34                emitter,
35                path_segment: Rc::default(),
36            }))),
37            Chunk::Seq(emitter) => Ok(Chunk::Seq(Box::new(PathSeqEmitter { emitter, index: 0 }))),
38            other => Ok(other),
39        }
40    }
41
42    fn finish(&self, state: &SerializerState) -> Result<(), Error> {
43        self.serializable.finish(state)
44    }
45}
46
47struct PathStructEmitter<'a> {
48    emitter: Box<dyn StructEmitter + 'a>,
49}
50
51impl<'a> StructEmitter for PathStructEmitter<'a> {
52    fn next(
53        &mut self,
54        state: &SerializerState,
55    ) -> Result<Option<(Cow<'_, str>, SerializeHandle)>, Error> {
56        let (key, value) = match self.emitter.next(state)? {
57            Some(result) => result,
58            None => return Ok(None),
59        };
60        let new_segment = PathSegment::Key(key.to_string());
61        let value_serializable = SegmentPushingSerializable {
62            serializable: value,
63            segment: RefCell::new(Some(new_segment)),
64        };
65        Ok(Some((key, SerializeHandle::boxed(value_serializable))))
66    }
67}
68
69struct PathMapEmitter<'a> {
70    emitter: Box<dyn MapEmitter + 'a>,
71    path_segment: Rc<RefCell<Option<PathSegment>>>,
72}
73
74impl<'a> MapEmitter for PathMapEmitter<'a> {
75    fn next_key(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error> {
76        let key_serializable = SegmentCollectingSerializable {
77            serializable: match self.emitter.next_key(state)? {
78                Some(result) => result,
79                None => return Ok(None),
80            },
81            segment: self.path_segment.clone(),
82        };
83        Ok(Some(SerializeHandle::boxed(key_serializable)))
84    }
85
86    fn next_value(&mut self, state: &SerializerState) -> Result<SerializeHandle, Error> {
87        let new_segment = self
88            .path_segment
89            .borrow_mut()
90            .take()
91            .unwrap_or(PathSegment::Unknown);
92        let value_serializable = SegmentPushingSerializable {
93            serializable: self.emitter.next_value(state)?,
94            segment: RefCell::new(Some(new_segment)),
95        };
96        Ok(SerializeHandle::boxed(value_serializable))
97    }
98}
99
100struct PathSeqEmitter<'a> {
101    emitter: Box<dyn SeqEmitter + 'a>,
102    index: usize,
103}
104
105impl<'a> SeqEmitter for PathSeqEmitter<'a> {
106    fn next(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error> {
107        let index = self.index;
108        self.index += 1;
109        let value = match self.emitter.next(state)? {
110            Some(result) => result,
111            None => return Ok(None),
112        };
113        let new_segment = PathSegment::Index(index);
114        let item_serializable = SegmentPushingSerializable {
115            serializable: value,
116            segment: RefCell::new(Some(new_segment)),
117        };
118        Ok(Some(SerializeHandle::boxed(item_serializable)))
119    }
120}
121
122struct SegmentPushingSerializable<'a> {
123    serializable: SerializeHandle<'a>,
124    segment: RefCell<Option<PathSegment>>,
125}
126
127impl<'a> Serialize for SegmentPushingSerializable<'a> {
128    fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
129        {
130            let mut path = state.get_mut::<Path>();
131            path.segments.push(self.segment.take().unwrap());
132        }
133        match self.serializable.serialize(state)? {
134            Chunk::Struct(emitter) => Ok(Chunk::Struct(Box::new(PathStructEmitter { emitter }))),
135            Chunk::Map(emitter) => Ok(Chunk::Map(Box::new(PathMapEmitter {
136                emitter,
137                path_segment: Rc::default(),
138            }))),
139            Chunk::Seq(emitter) => Ok(Chunk::Seq(Box::new(PathSeqEmitter { emitter, index: 0 }))),
140            other => Ok(other),
141        }
142    }
143
144    fn finish(&self, state: &SerializerState) -> Result<(), Error> {
145        self.serializable.finish(state)?;
146        let mut path = state.get_mut::<Path>();
147        path.segments.pop();
148        Ok(())
149    }
150}
151
152struct SegmentCollectingSerializable<'a> {
153    serializable: SerializeHandle<'a>,
154    segment: Rc<RefCell<Option<PathSegment>>>,
155}
156
157impl<'a> Serialize for SegmentCollectingSerializable<'a> {
158    fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
159        match self.serializable.serialize(state)? {
160            Chunk::Atom(Atom::Str(key)) => {
161                *self.segment.borrow_mut() = Some(PathSegment::Key(key.to_string()));
162                Ok(Chunk::Atom(Atom::Str(key)))
163            }
164            Chunk::Atom(Atom::U64(val)) => {
165                *self.segment.borrow_mut() = Some(PathSegment::Index(val as usize));
166                Ok(Chunk::Atom(Atom::U64(val)))
167            }
168            other => Ok(other),
169        }
170    }
171
172    fn finish(&self, state: &SerializerState) -> Result<(), Error> {
173        self.serializable.finish(state)
174    }
175}