use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec::Vec;
use core::marker::PhantomData;
use core::ptr::NonNull;
use crate::arena::{Alloc, Buffer};
use crate::error::Error;
use crate::ser::layer::{EventFn, Layer, Next};
use crate::ser::{
Begin, BeginKind, Boxed, ContainerShape, Emit, Erased, FIELDS_END, HandleInner, IndexedSeq,
IndexedStruct, PLAIN_BUDGET, PlainSink, Serialize, SerializeRef, StructField,
};
use crate::unwind::DropInReverse;
use crate::{Atom, Event, State};
use crate::{Context, Text};
use super::{MapEmitter, SeqEmitter, SerializeHandle, StructEmitter};
pub struct SerializeDriver<'a> {
state: State,
layers: Vec<Box<dyn Layer>>,
next_value: Option<Held>,
needs_finish: Option<(Held, bool)>,
stack: Vec<Frame>,
delivered: bool,
_marker: PhantomData<SerializeRef<'a>>,
}
struct Frame {
emitter: Emitter,
serializable: Held,
needs_finish: bool,
}
enum Emitter {
Seq(Boxed<dyn SeqEmitter>),
Map(Boxed<dyn MapEmitter>, bool),
Struct(Boxed<dyn StructEmitter>),
IndexedSeq(&'static dyn IndexedSeq, usize),
IndexedStruct(&'static dyn IndexedStruct, usize),
Forward,
}
impl Emitter {
#[inline(always)]
fn release(self, state: &mut State) {
match self {
Emitter::Seq(emitter) => Boxed::release(emitter, state),
Emitter::Map(emitter, _) => Boxed::release(emitter, state),
Emitter::Struct(emitter) => Boxed::release(emitter, state),
_ => {}
}
}
}
pub(crate) struct Held {
ptr: NonNull<dyn Erased>,
owned: Option<Alloc>,
}
unsafe impl Send for Held {}
impl Held {
#[inline]
pub(crate) unsafe fn new(handle: SerializeHandle<'_>) -> Held {
unsafe {
let (ptr, owned) = match handle.0 {
HandleInner::Borrowed(value) => (NonNull::from(value.as_dyn()), None),
HandleInner::Owned(value) => {
let (ptr, alloc) = Boxed::into_raw(value);
let ptr: NonNull<dyn Erased + '_> = ptr;
(ptr, Some(alloc))
}
};
Held {
ptr: core::mem::transmute::<NonNull<dyn Erased + '_>, NonNull<dyn Erased>>(ptr),
owned,
}
}
}
#[inline(always)]
pub(crate) unsafe fn get<'x>(&self) -> SerializeRef<'x> {
SerializeRef::from_dyn(unsafe { &*self.ptr.as_ptr() })
}
}
impl Drop for Held {
#[inline(always)]
fn drop(&mut self) {
#[cold]
#[inline(never)]
unsafe fn drop_owned(ptr: NonNull<dyn Erased>, alloc: Alloc) {
unsafe {
drop(Boxed::from_raw(ptr, alloc));
}
}
if let Some(alloc) = self.owned {
unsafe { drop_owned(self.ptr, alloc) };
}
}
}
impl<'a> Drop for SerializeDriver<'a> {
fn drop(&mut self) {
let frames = DropInReverse(&mut self.stack);
let needs_finish = self.needs_finish.take();
let next_value = self.next_value.take();
drop(next_value);
drop(needs_finish);
while let Some(frame) = frames.0.pop() {
frame.emitter.release(&mut self.state);
}
drop(frames);
let stack = core::mem::take(&mut self.stack);
self.state.arena.put_vec(Buffer::SerializeStack, stack);
}
}
const STACK_CAPACITY: usize = 128;
const _: () = {
const fn assert_send<T: Send>() {}
assert_send::<SerializeDriver<'static>>();
};
type NextEvent<'a> = Option<(Event<'a>, SerializeRef<'a>)>;
trait Callback {
const DESCRIBED: bool;
const PAUSABLE: bool = false;
const FAST: bool = !Self::DESCRIBED;
const UNBOUNDED: bool = Self::FAST && !Self::PAUSABLE;
fn call(
&mut self,
event: Event<'_>,
value: SerializeRef<'_>,
state: &mut State,
) -> Result<(), Error>;
#[inline(always)]
fn pause(&mut self) -> bool {
false
}
}
struct Plain<F>(F);
impl<F: FnMut(Event<'_>, &mut State) -> Result<(), Error>> Callback for Plain<F> {
const DESCRIBED: bool = false;
#[inline(always)]
fn call(
&mut self,
event: Event<'_>,
_value: SerializeRef<'_>,
state: &mut State,
) -> Result<(), Error> {
(self.0)(event, state)
}
}
pub trait EventSink {
const DESCRIBED: bool = false;
fn event(
&mut self,
event: Event<'_>,
value: SerializeRef<'_>,
state: &mut State,
) -> Result<(), Error>;
fn pause(&mut self) -> bool {
false
}
}
struct Sink<'s, S>(&'s mut S);
impl<S: EventSink> Callback for Sink<'_, S> {
const DESCRIBED: bool = S::DESCRIBED;
#[inline(always)]
fn call(
&mut self,
event: Event<'_>,
value: SerializeRef<'_>,
state: &mut State,
) -> Result<(), Error> {
self.0.event(event, value, state)
}
}
struct Pausable<'s, S>(&'s mut S);
impl<S: EventSink> Callback for Pausable<'_, S> {
const DESCRIBED: bool = S::DESCRIBED;
const PAUSABLE: bool = true;
#[inline(always)]
fn call(
&mut self,
event: Event<'_>,
value: SerializeRef<'_>,
state: &mut State,
) -> Result<(), Error> {
self.0.event(event, value, state)
}
#[inline(always)]
fn pause(&mut self) -> bool {
self.0.pause()
}
}
static FIELD_KEY: () = ();
#[inline(always)]
fn field_key() -> SerializeRef<'static> {
SerializeRef::new(&FIELD_KEY)
}
#[inline(never)]
fn serialize_plain<'x>(plain: SerializeRef<'x>, state: &mut State) -> Result<BeginKind<'x>, Error> {
Ok(BeginKind::Emit(plain.serialize(state)?))
}
struct PlainDelivery<'d, 'a, C> {
driver: &'d mut SerializeDriver<'a>,
f: &'d mut C,
}
impl<C: Callback> PlainDelivery<'_, '_, C> {
#[inline(always)]
fn begin(&mut self, event: Event<'_>) -> Result<(), Error> {
self.driver.deliver(self.f, event, field_key())?;
self.driver.state.is_map_key = false;
Ok(())
}
}
impl<C: Callback> PlainSink for PlainDelivery<'_, '_, C> {
#[inline]
fn atom(&mut self, atom: Atom<'_>) -> Result<(), Error> {
self.begin(Event::Atom(atom))
}
#[inline]
fn seq_start(&mut self, shape: ContainerShape) -> Result<(), Error> {
self.driver.state.depth += 1;
self.begin(Event::SeqStart(shape))
}
#[inline]
fn seq_end(&mut self) -> Result<(), Error> {
self.driver.state.depth -= 1;
self.driver.deliver(self.f, Event::SeqEnd, field_key())
}
#[inline]
fn map_start(&mut self, shape: ContainerShape) -> Result<(), Error> {
self.driver.state.depth += 1;
self.begin(Event::MapStart(shape))
}
#[inline]
fn map_end(&mut self) -> Result<(), Error> {
self.driver.state.depth -= 1;
self.driver.deliver(self.f, Event::MapEnd, field_key())
}
#[inline]
fn key(&mut self) {
self.driver.state.is_map_key = true;
}
#[inline]
fn field(&mut self, name: &str) -> Result<(), Error> {
self.driver.state.is_map_key = true;
self.begin(Event::Atom(Atom::Str(Text::borrowed(name))))
}
}
impl<'a> SerializeDriver<'a> {
#[inline]
pub fn new<T: Serialize>(value: &'a T) -> SerializeDriver<'a> {
SerializeDriver::from_ref(SerializeRef::new(value))
}
pub fn from_ref(serializable: SerializeRef<'a>) -> SerializeDriver<'a> {
let mut state = State::new();
let stack = state
.arena
.take_vec(Buffer::SerializeStack)
.unwrap_or_else(|| Vec::with_capacity(STACK_CAPACITY));
SerializeDriver {
state,
layers: Vec::new(),
next_value: Some(unsafe { Held::new(SerializeHandle::from(serializable)) }),
needs_finish: None,
stack,
delivered: false,
_marker: PhantomData,
}
}
pub fn state(&self) -> &State {
&self.state
}
pub fn state_mut(&mut self) -> &mut State {
&mut self.state
}
pub fn set_context(&mut self, context: Context) {
self.state.set_context(context);
}
#[inline(never)]
pub fn set_default_context(&mut self, context: Context) {
let mut merged = self.state.context().clone();
if merged.fill_from(&context) {
self.set_context(merged);
}
}
pub fn context(&self) -> &Context {
self.state.context()
}
pub fn push_layer<L: Layer + 'static>(&mut self, layer: L) {
self.layers.push(Box::new(layer));
}
#[allow(clippy::should_implement_trait)]
#[inline]
pub fn next(&mut self) -> Result<Option<(Event<'_>, SerializeRef<'_>, &mut State)>, Error> {
assert!(
self.layers.is_empty(),
"layers are only supported by SerializeDriver::drive"
);
let rv = match self.advance() {
Ok(rv) => rv,
Err(err) => return Err(self.state.error_in_context(err)),
};
self.delivered = rv.is_some();
Ok(rv.map(|(event, value)| (event, value, &mut self.state)))
}
#[inline(always)]
fn detach_delivered_event_data(&mut self) {
if self.delivered {
self.delivered = false;
self.state.clear_event_data();
}
}
#[inline]
pub fn drive<F>(&mut self, f: F) -> Result<(), Error>
where
F: FnMut(Event<'_>, &mut State) -> Result<(), Error>,
{
match self.drive_impl(Plain(f)) {
Ok(_) => Ok(()),
Err(err) => Err(self.state.error_in_context(err)),
}
}
#[inline]
pub fn drive_sink<S: EventSink>(&mut self, sink: &mut S) -> Result<(), Error> {
match self.drive_impl(Sink(sink)) {
Ok(_) => Ok(()),
Err(err) => Err(self.state.error_in_context(err)),
}
}
#[inline]
pub fn drive_until<S: EventSink>(&mut self, sink: &mut S) -> Result<bool, Error> {
match self.drive_impl(Pausable(sink)) {
Ok(done) => Ok(done),
Err(err) => Err(self.state.error_in_context(err)),
}
}
#[inline(always)]
fn deliver<C: Callback>(
&mut self,
f: &mut C,
event: Event<'_>,
value: SerializeRef<'_>,
) -> Result<(), Error> {
let value = if C::DESCRIBED { value } else { field_key() };
if self.layers.is_empty() {
f.call(event, value, &mut self.state)?;
} else {
self.deliver_layered(
&mut |event, value, state| f.call(event, value, state),
event,
value,
)?;
}
self.state.clear_event_data();
Ok(())
}
#[inline(never)]
fn deliver_layered(
&mut self,
f: &mut EventFn<'_>,
event: Event<'_>,
value: SerializeRef<'_>,
) -> Result<(), Error> {
Next::new(&mut self.layers, &mut self.state, f, value).emit(event)
}
#[inline(always)]
fn drive_impl<C: Callback>(&mut self, mut f: C) -> Result<bool, Error> {
self.detach_delivered_event_data();
if let Some((held, true)) = self.needs_finish.take() {
unsafe { held.get() }.finish(&mut self.state)?;
}
if let Some(value) = self.next_value.take() {
self.drive_value(value, false, &mut f)?;
}
let mut first = true;
while let Some(frame) = self.stack.last_mut() {
if C::PAUSABLE {
if !first && f.pause() {
return Ok(false);
}
first = false;
}
let emitter = unsafe { &mut *(&mut frame.emitter as *mut Emitter) };
let value = match emitter {
Emitter::Forward => {
self.finish_forward()?;
continue;
}
Emitter::IndexedStruct(fields, index) => {
if C::FAST {
*index = fields.emit_plain_fields(
*index,
C::PAUSABLE,
&mut PlainDelivery {
driver: self,
f: &mut f,
},
)?;
if *index == FIELDS_END {
self.drive_end(&mut f)?;
continue;
}
}
let field = fields.field(*index);
*index += 1;
match field {
StructField::Field(key, value) => {
self.state.is_map_key = true;
self.deliver(
&mut f,
Event::Atom(Atom::Str(Text::borrowed(key))),
field_key(),
)?;
(value, false)
}
StructField::Skip => continue,
StructField::End => {
self.drive_end(&mut f)?;
continue;
}
}
}
Emitter::IndexedSeq(seq, index) => {
if C::FAST && C::PAUSABLE {
self.state.is_map_key = false;
let next = seq.emit_plain_chunk(
*index,
PLAIN_BUDGET,
&mut PlainDelivery {
driver: self,
f: &mut f,
},
)?;
if next != *index {
*index = next;
continue;
}
}
let element = seq.element(*index, &mut self.state)?;
*index += 1;
match element {
Some(value) => (value, false),
None => {
self.drive_end(&mut f)?;
continue;
}
}
}
Emitter::Struct(emitter) => match emitter.next(&mut self.state)? {
Some((key, value)) => {
self.state.is_map_key = true;
self.deliver(&mut f, Event::Atom(Atom::Str(key.into())), field_key())?;
(value, false)
}
None => {
self.drive_end(&mut f)?;
continue;
}
},
Emitter::Seq(emitter) => match emitter.next(&mut self.state)? {
Some(value) => (value, false),
None => {
self.drive_end(&mut f)?;
continue;
}
},
Emitter::Map(emitter, is_value) => {
if *is_value {
*is_value = false;
(emitter.next_value(&mut self.state)?, false)
} else {
match emitter.next_key(&mut self.state)? {
Some(key) => {
*is_value = true;
(key, true)
}
None => {
self.drive_end(&mut f)?;
continue;
}
}
}
}
};
self.drive_value(unsafe { Held::new(value.0) }, value.1, &mut f)?;
}
Ok(true)
}
#[cold]
fn finish_forward(&mut self) -> Result<(), Error> {
let Frame {
emitter,
serializable,
needs_finish,
} = self.stack.pop().unwrap();
debug_assert!(matches!(emitter, Emitter::Forward));
if needs_finish {
unsafe { serializable.get() }.finish(&mut self.state)?;
}
Ok(())
}
#[cold]
fn push_forward(
&mut self,
value: Held,
needs_finish: bool,
forwarded: SerializeHandle<'_>,
) -> Held {
self.stack.push(Frame {
emitter: Emitter::Forward,
serializable: value,
needs_finish,
});
unsafe { Held::new(forwarded) }
}
#[inline(never)]
fn drive_forwarded<C: Callback>(
&mut self,
value: Held,
is_key: bool,
f: &mut C,
) -> Result<(), Error> {
self.drive_value(value, is_key, f)
}
#[inline(always)]
fn drive_value<C: Callback>(
&mut self,
value: Held,
is_key: bool,
f: &mut C,
) -> Result<(), Error> {
let serializable = unsafe { value.get() };
self.state.is_map_key = is_key;
let Begin {
kind,
shape,
needs_finish,
} = serializable.begin(&mut self.state)?;
let kind = match kind {
BeginKind::Plain(plain)
if C::UNBOUNDED || (C::FAST && plain.plain_cost(PLAIN_BUDGET).is_some()) =>
{
return plain.emit_plain(&mut PlainDelivery { driver: self, f });
}
BeginKind::Plain(plain) => serialize_plain(plain, &mut self.state)?,
kind => kind,
};
let (emitter, event) = match kind {
BeginKind::Emit(Emit::Atom(atom)) => {
self.deliver(f, Event::Atom(atom), serializable)?;
if needs_finish {
serializable.finish(&mut self.state)?;
}
return Ok(());
}
BeginKind::Emit(Emit::Struct(emitter)) => {
(Emitter::Struct(emitter), Event::MapStart(shape))
}
BeginKind::Emit(Emit::Map(emitter)) => {
(Emitter::Map(emitter, false), Event::MapStart(shape))
}
BeginKind::Emit(Emit::Seq(emitter)) => (Emitter::Seq(emitter), Event::SeqStart(shape)),
BeginKind::Struct(fields) if C::FAST => {
let mut value = Some(value);
let rv = self.drive_indexed_struct(&mut value, fields, shape, f);
drop(value);
return rv;
}
BeginKind::Struct(fields) => {
(Emitter::IndexedStruct(fields, 0), Event::MapStart(shape))
}
BeginKind::Seq(seq)
if C::UNBOUNDED || (C::FAST && serializable.plain_cost(PLAIN_BUDGET).is_some()) =>
{
let mut value = Some(value);
let rv = self.drive_indexed_seq(&mut value, seq, shape, f);
drop(value);
return rv;
}
BeginKind::Seq(seq) => (Emitter::IndexedSeq(seq, 0), Event::SeqStart(shape)),
BeginKind::Emit(Emit::Forward(forwarded)) => {
let forwarded = self.push_forward(value, needs_finish, forwarded);
return self.drive_forwarded(forwarded, is_key, f);
}
BeginKind::Plain(_) => unreachable!(),
};
self.stack.push(Frame {
emitter,
serializable: value,
needs_finish,
});
self.state.depth += 1;
self.deliver(f, event, serializable)
}
#[inline(always)]
fn drive_indexed_struct<C: Callback>(
&mut self,
value: &mut Option<Held>,
fields: &'static dyn IndexedStruct,
shape: ContainerShape,
f: &mut C,
) -> Result<(), Error> {
let serializable = unsafe { value.as_ref().unwrap().get() };
self.state.depth += 1;
self.deliver(f, Event::MapStart(shape), serializable)?;
self.state.is_map_key = false;
let index =
fields.emit_plain_fields(0, C::PAUSABLE, &mut PlainDelivery { driver: self, f })?;
if index == FIELDS_END {
self.state.depth -= 1;
self.deliver(f, Event::MapEnd, serializable)
} else {
self.stack.push(Frame {
emitter: Emitter::IndexedStruct(fields, index),
serializable: value.take().unwrap(),
needs_finish: false,
});
Ok(())
}
}
#[inline(always)]
fn drive_indexed_seq<C: Callback>(
&mut self,
value: &mut Option<Held>,
seq: &'static dyn IndexedSeq,
shape: ContainerShape,
f: &mut C,
) -> Result<(), Error> {
let serializable = unsafe { value.as_ref().unwrap().get() };
self.state.depth += 1;
self.deliver(f, Event::SeqStart(shape), serializable)?;
self.state.is_map_key = false;
let emitted = seq.emit_plain(&mut PlainDelivery { driver: self, f })?;
if emitted {
self.state.depth -= 1;
self.deliver(f, Event::SeqEnd, serializable)
} else {
self.stack.push(Frame {
emitter: Emitter::IndexedSeq(seq, 0),
serializable: value.take().unwrap(),
needs_finish: false,
});
Ok(())
}
}
#[inline]
fn drive_end<C: Callback>(&mut self, f: &mut C) -> Result<(), Error> {
let Frame {
emitter,
serializable,
needs_finish,
} = self.stack.pop().unwrap();
let event = match emitter {
Emitter::Seq(_) | Emitter::IndexedSeq(..) => Event::SeqEnd,
_ => Event::MapEnd,
};
emitter.release(&mut self.state);
self.state.depth -= 1;
let value = unsafe { serializable.get() };
self.deliver(f, event, value)?;
if needs_finish {
value.finish(&mut self.state)?;
}
Ok(())
}
fn advance(&mut self) -> Result<NextEvent<'static>, Error> {
self.detach_delivered_event_data();
if let Some((held, true)) = self.needs_finish.take() {
unsafe { held.get() }.finish(&mut self.state)?;
}
let mut is_key = false;
let value = match self.next_value.take() {
Some(value) => value,
None => loop {
let frame = match self.stack.last_mut() {
Some(frame) => frame,
None => return Ok(None),
};
let emitter = unsafe { &mut *(&mut frame.emitter as *mut Emitter) };
let next = match emitter {
Emitter::Forward => {
self.finish_forward()?;
continue;
}
Emitter::Seq(emitter) => emitter.next(&mut self.state)?,
Emitter::Map(emitter, is_value) => {
if *is_value {
*is_value = false;
Some(emitter.next_value(&mut self.state)?)
} else {
let key = emitter.next_key(&mut self.state)?;
*is_value = key.is_some();
is_key = true;
key
}
}
Emitter::Struct(emitter) => match emitter.next(&mut self.state)? {
Some((key, value)) => {
self.next_value = Some(unsafe { Held::new(value) });
let key = unsafe {
core::mem::transmute::<Cow<'_, str>, Cow<'static, str>>(key)
};
self.state.is_map_key = true;
return Ok(Some((Event::Atom(Atom::Str(key.into())), field_key())));
}
None => None,
},
Emitter::IndexedSeq(seq, index) => {
let rv = seq.element(*index, &mut self.state)?;
*index += 1;
rv
}
Emitter::IndexedStruct(fields, index) => loop {
let field = fields.field(*index);
*index += 1;
match field {
StructField::Field(key, value) => {
self.next_value = Some(unsafe { Held::new(value) });
self.state.is_map_key = true;
return Ok(Some((
Event::Atom(Atom::Str(Text::borrowed(key))),
field_key(),
)));
}
StructField::Skip => continue,
StructField::End => break None,
}
},
};
match next {
Some(value) => break unsafe { Held::new(value) },
None => {
let event = self.end_container();
return Ok(Some((event, unsafe { self.finished_value() })));
}
}
},
};
self.serialize_value(value, is_key)
}
fn end_container(&mut self) -> Event<'static> {
let Frame {
emitter,
serializable,
needs_finish,
} = self.stack.pop().unwrap();
let event = match emitter {
Emitter::Seq(_) | Emitter::IndexedSeq(..) => Event::SeqEnd,
_ => Event::MapEnd,
};
emitter.release(&mut self.state);
self.needs_finish = Some((serializable, needs_finish));
self.state.depth -= 1;
event
}
#[inline(always)]
unsafe fn finished_value(&self) -> SerializeRef<'static> {
match self.needs_finish {
Some((ref held, _)) => unsafe { held.get() },
None => field_key(),
}
}
#[inline]
fn serialize_value(&mut self, value: Held, is_key: bool) -> Result<NextEvent<'static>, Error> {
let serializable = unsafe { value.get() };
self.state.is_map_key = is_key;
let Begin {
kind,
shape,
needs_finish,
} = serializable.begin(&mut self.state)?;
let kind = match kind {
BeginKind::Plain(plain) => serialize_plain(plain, &mut self.state)?,
kind => kind,
};
let (emitter, event) = match kind {
BeginKind::Emit(Emit::Atom(atom)) => {
self.needs_finish = Some((value, needs_finish));
return Ok(Some((Event::Atom(atom), serializable)));
}
BeginKind::Emit(Emit::Struct(emitter)) => {
(Emitter::Struct(emitter), Event::MapStart(shape))
}
BeginKind::Emit(Emit::Map(emitter)) => {
(Emitter::Map(emitter, false), Event::MapStart(shape))
}
BeginKind::Emit(Emit::Seq(emitter)) => (Emitter::Seq(emitter), Event::SeqStart(shape)),
BeginKind::Struct(fields) => {
(Emitter::IndexedStruct(fields, 0), Event::MapStart(shape))
}
BeginKind::Seq(seq) => (Emitter::IndexedSeq(seq, 0), Event::SeqStart(shape)),
BeginKind::Emit(Emit::Forward(forwarded)) => {
let forwarded = self.push_forward(value, needs_finish, forwarded);
return self.serialize_forwarded(forwarded, is_key);
}
BeginKind::Plain(_) => unreachable!(),
};
self.stack.push(Frame {
emitter,
serializable: value,
needs_finish,
});
self.state.depth += 1;
Ok(Some((event, serializable)))
}
#[inline(never)]
fn serialize_forwarded(
&mut self,
value: Held,
is_key: bool,
) -> Result<NextEvent<'static>, Error> {
self.serialize_value(value, is_key)
}
}
#[test]
fn test_seq_emitting() {
let vec = vec![vec![1u64, 2], vec![3, 4]];
let mut driver = SerializeDriver::new(&vec);
let mut events = Vec::new();
while let Some((event, _, _)) = driver.next().unwrap() {
events.push(crate::event::without_len(event.to_static()));
}
assert_eq!(
events,
vec![
Event::seq_start(),
Event::seq_start(),
1u64.into(),
2u64.into(),
Event::SeqEnd,
Event::seq_start(),
3u64.into(),
4u64.into(),
Event::SeqEnd,
Event::SeqEnd,
],
);
}
#[test]
fn test_map_emitting() {
let mut map = alloc::collections::BTreeMap::new();
map.insert((1u32, 2u32), "first");
map.insert((2, 3), "second");
let mut driver = SerializeDriver::new(&map);
let mut events = Vec::new();
while let Some((event, _, _)) = driver.next().unwrap() {
events.push(crate::event::without_len(event.to_static()));
}
assert_eq!(
events,
vec![
Event::MapStart(crate::ContainerShape::with_order(crate::Order::Sorted)),
Event::seq_start(),
1u64.into(),
2u64.into(),
Event::SeqEnd,
"first".into(),
Event::seq_start(),
2u64.into(),
3u64.into(),
Event::SeqEnd,
"second".into(),
Event::MapEnd
]
);
}
#[test]
fn test_state_mut() {
#[derive(Debug, Default)]
struct Uppercase(bool);
struct Name(&'static str);
impl Serialize for Name {
fn serialize<'a>(value: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
Ok(Emit::Atom(Atom::Str(
if state.get::<Uppercase>().is_some_and(|x| x.0) {
value.0.to_uppercase().into()
} else {
value.0.into()
},
)))
}
}
let names = vec![Name("foo"), Name("bar")];
let mut driver = SerializeDriver::new(&names);
driver.state_mut().get_mut::<Uppercase>().0 = true;
let mut events = Vec::new();
while let Some((event, _, _)) = driver.next().unwrap() {
events.push(crate::event::without_len(event.to_static()));
}
assert_eq!(
events,
vec![
Event::seq_start(),
"FOO".into(),
"BAR".into(),
Event::SeqEnd
],
);
}