use deser_core::ser::{Layer, Next};
use deser_core::{Error, Event, State};
use crate::{Frame, Path, PathLayer, PathSegment};
impl Layer for PathLayer {
fn event(&mut self, event: Event<'_>, next: &mut Next<'_>) -> Result<(), Error> {
if !self.registered {
self.register(next.state_mut(), false);
}
match event {
Event::MapEnd | Event::SeqEnd => {
if let Some(Frame::Seq(_)) = self.frames.pop() {
next.state_mut().get_mut::<Path>().pop();
}
next.emit(event)?;
self.complete_item(next.state_mut(), None);
}
Event::MapStart(_) | Event::SeqStart(_) => {
let is_map = matches!(event, Event::MapStart(_));
next.emit(event)?;
if is_map {
self.frames.push(Frame::Map(false));
} else {
self.frames.push(Frame::Seq(0));
next.state_mut()
.get_mut::<Path>()
.push(PathSegment::Index(0));
}
}
Event::Atom(ref atom) => {
let key = match self.frames.last() {
Some(Frame::Map(false)) => {
Some(next.state_mut().get_mut::<Path>().key_segment(atom))
}
_ => None,
};
next.emit(event)?;
self.complete_item(next.state_mut(), key);
}
}
Ok(())
}
}
impl PathLayer {
fn complete_item(&mut self, state: &mut State, key: Option<PathSegment>) {
match self.frames.last_mut() {
Some(Frame::Map(in_value)) => {
let path = state.get_mut::<Path>();
if *in_value {
path.pop();
} else {
path.push(key.unwrap_or(PathSegment::Unknown));
}
*in_value = !*in_value;
}
Some(Frame::Seq(index)) => {
*index += 1;
let index = *index;
state.get_mut::<Path>().set_last(PathSegment::Index(index));
}
None => {}
}
}
}