use crate::State;
use crate::de::{Deserialize, DeserializeDriver, SinkHandle};
use crate::error::{Error, ErrorKind};
pub trait Deserializer<'de> {
fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'de>) -> Result<(), Error>;
fn deserialize<T: Deserialize<'de>>(&mut self) -> Result<T, Error>
where
Self: Sized,
{
self.deserialize_with(|_| {})
}
fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
where
T: Deserialize<'de>,
F: FnOnce(&mut DeserializeDriver<'_, 'de>),
Self: Sized,
{
let mut setup = Some(setup);
deserialize_value(|make_sink| {
drive_new(self, make_sink, &mut |driver| {
if let Some(setup) = setup.take() {
setup(driver);
}
})
})
}
fn update<T: Deserialize<'de>>(&mut self, value: &mut T) -> Result<(), Error>
where
Self: Sized,
{
self.update_with(value, |_| {})
}
fn update_with<T, F>(&mut self, value: &mut T, setup: F) -> Result<(), Error>
where
T: Deserialize<'de>,
F: FnOnce(&mut DeserializeDriver<'_, 'de>),
Self: Sized,
{
let mut driver = DeserializeDriver::update(value);
setup(&mut driver);
self.drive(&mut driver)
}
}
pub type MakeSink<'m, 'out, 'de> = dyn FnMut(&mut State) -> SinkHandle<'out, 'de> + 'm;
#[inline]
pub fn deserialize_value<'de, T: Deserialize<'de>>(
drive: impl for<'out> FnOnce(&mut MakeSink<'_, 'out, 'de>) -> Result<(), Error>,
) -> Result<T, Error> {
let mut out = None;
{
let mut slot = Some(&mut out);
drive(&mut |state| match slot.take() {
Some(slot) => T::deserialize_into(slot, state),
None => panic!("the sink of a value was created twice"),
})?;
}
out.ok_or_else(empty_input)
}
#[inline(never)]
pub fn drive_value<'out, 'de>(
de: &mut dyn Deserializer<'de>,
make_sink: &mut MakeSink<'_, 'out, 'de>,
) -> Result<(), Error> {
drive_new(de, make_sink, &mut |_| {})
}
#[inline(never)]
fn drive_new<'out, 'de>(
de: &mut dyn Deserializer<'de>,
make_sink: &mut MakeSink<'_, 'out, 'de>,
setup: &mut dyn FnMut(&mut DeserializeDriver<'_, 'de>),
) -> Result<(), Error> {
let mut state = State::new();
let sink = make_sink(&mut state);
let mut driver = DeserializeDriver::from_state(state, sink);
setup(&mut driver);
de.drive(&mut driver)
}
#[cold]
fn empty_input() -> Error {
Error::new(ErrorKind::EndOfFile, "empty input")
}