use std::sync::Arc;
use deser_core::Text;
use deser_core::de::{self, Deserialize, DeserializeDriver};
use deser_core::ser::{self, Serialize, SerializeDriver};
use deser_core::{Atom, ContainerShape, Error, ErrorKind, Event, Source};
use crate::value::{Kind, Value};
pub struct Deserializer<'a> {
value: &'a Value,
context: deser_core::Context,
}
impl<'a> Deserializer<'a> {
pub fn new(value: &'a Value) -> Deserializer<'a> {
Deserializer {
value,
context: deser_core::Context::new(),
}
}
pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
de::Deserializer::deserialize(self)
}
pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
where
T: Deserialize<'a>,
F: FnOnce(&mut DeserializeDriver<'_, 'a>),
{
de::Deserializer::deserialize_with(self, setup)
}
pub fn set_context(&mut self, context: deser_core::Context) {
self.context = context;
}
pub fn context(&self) -> &deser_core::Context {
&self.context
}
}
impl<'de> de::Deserializer<'de> for Deserializer<'de> {
fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'de>) -> Result<(), Error> {
if !self.context.is_empty() {
driver.set_default_context(self.context.clone());
}
let mut source = None;
drive(self.value, driver, &mut source).map_err(|mut err| {
if let Some(source) = source {
err.resolve_position(source.as_bytes());
}
err
})
}
}
enum Frame<'a> {
Seq(std::slice::Iter<'a, Value>, &'a Value),
Map(MapFrame<'a>, &'a Value),
}
struct MapFrame<'a> {
iter: indexmap::map::Iter<'a, Value, Value>,
pending: Option<&'a Value>,
repeated: Option<(&'a Value, std::slice::Iter<'a, Value>)>,
multimap: bool,
}
impl<'a> MapFrame<'a> {
fn next(&mut self) -> Option<&'a Value> {
if let Some(value) = self.pending.take() {
return Some(value);
}
if let Some((key, ref mut values)) = self.repeated {
if let Some(value) = values.next() {
self.pending = Some(value);
return Some(key);
}
self.repeated = None;
}
let (key, value) = self.iter.next()?;
if self.multimap
&& let Some(seq) = value.as_seq()
&& seq.is_repeated()
&& !seq.is_empty()
{
let mut values = seq.iter();
self.pending = values.next();
self.repeated = Some((key, values));
} else {
self.pending = Some(value);
}
Some(key)
}
}
fn set_range<'de>(
driver: &mut DeserializeDriver<'_, 'de>,
current: &mut Option<&'de Arc<str>>,
new: &'de Arc<str>,
(start, end): (usize, usize),
) {
if !current.is_some_and(|current| Arc::ptr_eq(current, new)) {
Source(new.clone()).set(driver.state_mut());
*current = Some(new);
}
driver.state_mut().set_input_range(start, end);
}
fn drive<'de>(
root: &'de Value,
driver: &mut DeserializeDriver<'_, 'de>,
source: &mut Option<&'de Arc<str>>,
) -> Result<(), Error> {
let mut stack: Vec<Frame<'de>> = Vec::new();
let mut next = Some(root);
loop {
if let Some(value) = next.take() {
if let Some(ref meta) = value.meta {
if !meta.event_data().is_empty() {
driver.state_mut().attach_event_data(meta.event_data());
}
if let Some(span) = meta.span() {
set_range(driver, source, span.source(), span.start_range());
}
}
match value.kind {
Kind::Seq(ref seq) => {
let mut seq_shape = shape(seq.len(), seq.order());
seq_shape.set_ambiguous_empty(seq.is_ambiguous_empty());
driver.emit(Event::SeqStart(seq_shape))?;
stack.push(Frame::Seq(seq.iter(), value));
}
Kind::Map(ref map) => {
let mut map_shape = shape(map.len(), map.order());
map_shape.set_ambiguous_empty(map.is_ambiguous_empty());
if map.is_multimap() {
map_shape = {
let mut shape = ContainerShape::with_order(map.order());
shape.set_multimap(true);
shape
};
}
driver.emit(Event::MapStart(map_shape))?;
stack.push(Frame::Map(
MapFrame {
iter: map.inner.entries.iter(),
pending: None,
repeated: None,
multimap: map.is_multimap(),
},
value,
));
}
ref leaf => driver.emit_borrowed(leaf_atom(leaf))?,
}
}
let Some(frame) = stack.last_mut() else {
return Ok(());
};
next = match frame {
Frame::Seq(iter, _) => iter.next(),
Frame::Map(map, _) => map.next(),
};
if next.is_none() {
let (container, event) = match stack.pop() {
Some(Frame::Seq(_, container)) => (container, Event::SeqEnd),
Some(Frame::Map(_, container)) => (container, Event::MapEnd),
None => unreachable!(),
};
if let Some(span) = container.span()
&& let Some(range) = span.end_range()
{
set_range(driver, source, span.source(), range);
}
driver.emit(event)?;
}
}
}
fn shape(len: usize, order: deser_core::Order) -> ContainerShape {
{
let mut shape = ContainerShape::with_len(len);
shape.set_order(order);
shape
}
}
fn leaf_atom(kind: &Kind) -> Atom<'_> {
match kind {
Kind::Null => Atom::Null,
Kind::Bool(value) => Atom::Bool(*value),
Kind::U64(value) => Atom::U64(*value),
Kind::I64(value) => Atom::I64(*value),
Kind::F32(value) => Atom::F32(*value),
Kind::F64(value) => Atom::F64(*value),
Kind::Char(value) => Atom::Char(*value),
Kind::Str(value) => Atom::Str(Text::borrowed(value)),
Kind::Lexical(value) => Atom::Lexical(Text::borrowed(value)),
Kind::Bytes(value) => Atom::Bytes(value.as_borrowed()),
Kind::Ext(value) => Atom::Ext(value.as_borrowed()),
Kind::Implicit(value) => Atom::Implicit(value.as_borrowed()),
Kind::Seq(_) | Kind::Map(_) => unreachable!("containers are not atoms"),
}
}
pub fn from_value<'de, T: Deserialize<'de>>(value: &'de Value) -> Result<T, Error> {
Deserializer::new(value).deserialize()
}
pub fn to_value<T: Serialize>(value: &T) -> Result<Value, Error> {
let mut serializer = Serializer::new();
serializer.serialize(value)?;
Ok(serializer.finish().pop().expect("a value was serialized"))
}
#[derive(Debug, Default, Clone)]
pub struct Serializer {
values: Vec<Value>,
context: deser_core::Context,
}
impl Serializer {
pub fn new() -> Serializer {
Serializer::default()
}
pub fn serialize<T: Serialize + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
ser::Serializer::serialize(self, value)
}
pub fn serialize_with<F, T: Serialize + ?Sized>(
&mut self,
value: &T,
setup: F,
) -> Result<(), Error>
where
F: FnOnce(&mut SerializeDriver<'_>),
{
ser::Serializer::serialize_with(self, value, setup)
}
pub fn values(&self) -> &[Value] {
&self.values
}
pub fn finish(self) -> Vec<Value> {
self.values
}
pub fn set_context(&mut self, context: deser_core::Context) {
self.context = context;
}
pub fn context(&self) -> &deser_core::Context {
&self.context
}
}
impl ser::Serializer for Serializer {
fn drive(&mut self, driver: &mut SerializeDriver<'_>) -> Result<(), Error> {
if !self.context.is_empty() {
driver.set_default_context(self.context.clone());
}
let mut out = None;
{
let mut de = DeserializeDriver::new(&mut out);
driver.drive(|event, state| {
de.state_mut()
.attach_event_data(&state.capture_event_data());
de.emit(event)
})?;
}
let value =
out.ok_or_else(|| Error::new(ErrorKind::EndOfFile, "no value was serialized"))?;
self.values.push(value);
Ok(())
}
}