diff --git a/deser-debug/src/lib.rs b/deser-debug/src/lib.rs index 648211d..c341851 100644 --- a/deser-debug/src/lib.rs +++ b/deser-debug/src/lib.rs @@ -8,7 +8,7 @@ use deser::{Atom, Event}; /// Serializes a serializable value to `Debug` format. pub struct ToDebug { - events: Vec<(Event<'static>, Option)>, + events: Vec>, } impl fmt::Display for ToDebug { @@ -28,19 +28,19 @@ impl ToDebug { pub fn new(value: &dyn Serialize) -> ToDebug { let mut events = Vec::new(); let mut driver = SerializeDriver::new(value); - while let Some((event, descriptor, _)) = driver.next().unwrap() { - events.push((event.to_static(), descriptor.name().map(|x| x.to_string()))); + while let Some((event, _)) = driver.next().unwrap() { + events.push(event.to_static()); } ToDebug { events } } } fn dump<'a, 'f>( - tokens: &'a [(Event<'a>, Option)], + tokens: &'a [Event<'a>], f: &'f mut fmt::Formatter<'_>, -) -> Result<&'a [(Event<'a>, Option)], fmt::Error> { +) -> Result<&'a [Event<'a>], fmt::Error> { if let Some((first, mut rest)) = tokens.split_first() { - match first.0 { + match first { Event::Atom(Atom::Null) => fmt::Debug::fmt(&(), f)?, Event::Atom(Atom::Bool(v)) => fmt::Debug::fmt(&v, f)?, Event::Atom(Atom::Str(ref v)) => fmt::Debug::fmt(v, f)?, @@ -71,13 +71,10 @@ fn dump<'a, 'f>( Event::Atom(Atom::F64(v)) => fmt::Debug::fmt(&v, f)?, Event::Atom(..) => f.debug_struct("?").finish()?, Event::MapStart => { - if let Some(ref name) = first.1 { - write!(f, "{} ", name)?; - } let mut map = f.debug_map(); let mut is_key = true; loop { - if rest.get(0).map_or(false, |x| matches!(x.0, Event::MapEnd)) { + if rest.get(0).map_or(false, |x| matches!(x, Event::MapEnd)) { rest = &rest[1..]; break; } @@ -94,14 +91,9 @@ fn dump<'a, 'f>( } Event::MapEnd => unreachable!(), Event::SeqStart => { - if let Some(ref name) = first.1 { - if name != "Vec" && name != "slice" { - write!(f, "{} ", name)?; - } - } let mut list = f.debug_list(); loop { - if rest.get(0).map_or(false, |x| matches!(x.0, Event::SeqEnd)) { + if rest.get(0).map_or(false, |x| matches!(x, Event::SeqEnd)) { rest = &rest[1..]; break; } @@ -119,7 +111,7 @@ fn dump<'a, 'f>( } } -struct Helper<'a>(&'a [(Event<'a>, Option)], AtomicUsize); +struct Helper<'a>(&'a [Event<'a>], AtomicUsize); impl<'a> fmt::Debug for Helper<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -138,6 +130,6 @@ fn test_debug_format() { assert_eq!( ToDebug::new(&m).to_string(), - "BTreeMap {false: [], true: [[b\"x\", b\"yyy\"], [b\"zzzz\\0\\x01\"]]}" + "{false: [], true: [[b\"x\", b\"yyy\"], [b\"zzzz\\0\\x01\"]]}" ); } diff --git a/deser-derive/src/de.rs b/deser-derive/src/de.rs index 13784ad..e8f88ad 100644 --- a/deser-derive/src/de.rs +++ b/deser-derive/src/de.rs @@ -32,7 +32,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re ); let container_attrs = ContainerAttrs::of(input)?; - let type_name = container_attrs.container_name(); let attrs = fields .named .iter() @@ -251,10 +250,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re #[automatically_derived] impl #wrapper_impl_generics ::deser::de::Sink for __Sink #wrapper_ty_generics #bounded_where_clause { - fn descriptor(&self) -> &dyn ::deser::Descriptor { - &__Descriptor - } - fn map(&mut self, __state: &::deser::de::DeserializerState) -> ::deser::__derive::Result<()> { @@ -312,14 +307,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re ::deser::__derive::Ok(()) } } - - struct __Descriptor; - - impl ::deser::Descriptor for __Descriptor { - fn name(&self) -> ::deser::__derive::Option<&::deser::__derive::str> { - ::deser::__derive::Some(#type_name) - } - } }; }) } @@ -451,8 +438,6 @@ fn derive_newtype_struct(input: &syn::DeriveInput, field: &syn::Field) -> syn::R Span::call_site(), ); - // TODO: we want to report the type name here but the current descriptor - // interface does not let us. https://github.com/mitsuhiko/deser/issues/8 let container_attrs = ContainerAttrs::of(input)?; let _type_name = container_attrs.container_name(); @@ -526,10 +511,6 @@ fn derive_newtype_struct(input: &syn::DeriveInput, field: &syn::Field) -> syn::R Ok(()) } - fn descriptor(&self) -> &dyn ::deser::Descriptor { - self.sink.borrow().descriptor() - } - fn expecting(&self) -> ::deser::__derive::StrCow<'_> { self.sink.borrow().expecting() } diff --git a/deser-derive/src/ser.rs b/deser-derive/src/ser.rs index 79206d8..8a4f707 100644 --- a/deser-derive/src/ser.rs +++ b/deser-derive/src/ser.rs @@ -28,7 +28,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re ); let container_attrs = ContainerAttrs::of(input)?; - let type_name = container_attrs.container_name(); let attrs = fields .named .iter() @@ -153,9 +152,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re const #dummy: () = { #[automatically_derived] impl #impl_generics ::deser::Serialize for #ident #ty_generics #bounded_where_clause { - fn descriptor(&self) -> &dyn ::deser::Descriptor { - &__Descriptor - } fn serialize(&self, __state: &::deser::ser::SerializerState) -> ::deser::__derive::Result<::deser::ser::Chunk> { ::deser::__derive::Ok(::deser::ser::Chunk::Struct(Box::new(__StructEmitter { data: self, @@ -171,14 +167,6 @@ fn derive_struct(input: &syn::DeriveInput, fields: &syn::FieldsNamed) -> syn::Re #temp_emitter } - struct __Descriptor; - - impl ::deser::Descriptor for __Descriptor { - fn name(&self) -> ::deser::__derive::Option<&::deser::__derive::str> { - ::deser::__derive::Some(#type_name) - } - } - #[automatically_derived] impl #wrapper_impl_generics ::deser::ser::StructEmitter for __StructEmitter #wrapper_ty_generics #bounded_where_clause { fn next(&mut self, __state: &::deser::ser::SerializerState) @@ -265,8 +253,6 @@ fn derive_newtype_struct(input: &syn::DeriveInput, field: &syn::Field) -> syn::R Span::call_site(), ); - // TODO: we want to report the type name here but the current descriptor - // interface does not let us. https://github.com/mitsuhiko/deser/issues/8 let container_attrs = ContainerAttrs::of(input)?; let _type_name = container_attrs.container_name(); @@ -280,9 +266,6 @@ fn derive_newtype_struct(input: &syn::DeriveInput, field: &syn::Field) -> syn::R const #dummy: () = { #[automatically_derived] impl #impl_generics ::deser::Serialize for #ident #ty_generics #bounded_where_clause { - fn descriptor(&self) -> &dyn ::deser::Descriptor { - self.0.descriptor() - } fn serialize(&self, __state: &::deser::ser::SerializerState) -> ::deser::__derive::Result<::deser::ser::Chunk> { ::deser::ser::Serialize::serialize(&self.0, __state) } diff --git a/deser-json/src/ser.rs b/deser-json/src/ser.rs index a5786de..69c7e9f 100644 --- a/deser-json/src/ser.rs +++ b/deser-json/src/ser.rs @@ -34,7 +34,7 @@ impl Serializer { }}; } - while let Some((event, _, _)) = driver.next()? { + while let Some((event, _)) = driver.next()? { // try to exit containers first match event { Event::MapEnd => { diff --git a/deser-path/src/de.rs b/deser-path/src/de.rs index 9023b9b..9341eac 100644 --- a/deser-path/src/de.rs +++ b/deser-path/src/de.rs @@ -3,7 +3,7 @@ use std::cell::RefCell; use std::rc::Rc; use deser::de::{DeserializerState, Sink, SinkHandle}; -use deser::{Atom, Descriptor, Error}; +use deser::{Atom, Error}; use crate::{Path, PathSegment}; @@ -106,10 +106,6 @@ impl<'a> Sink for PathSink<'a> { self.sink.finish(state) } - fn descriptor(&self) -> &dyn Descriptor { - self.sink.descriptor() - } - fn expecting(&self) -> Cow<'_, str> { self.sink.expecting() } diff --git a/deser-path/tests/ser.rs b/deser-path/tests/ser.rs index b379a73..80efb2f 100644 --- a/deser-path/tests/ser.rs +++ b/deser-path/tests/ser.rs @@ -22,7 +22,7 @@ fn test_path() { let serializable = PathSerializable::wrap(&map); let mut driver = SerializeDriver::new(&serializable); - while let Some((event, _, state)) = driver.next().unwrap() { + while let Some((event, state)) = driver.next().unwrap() { events.push(format!("{:?}|{:?}", event, state.get::().segments())); } diff --git a/deser/src/de/driver.rs b/deser/src/de/driver.rs index 10c18cf..11bc3f7 100644 --- a/deser/src/de/driver.rs +++ b/deser/src/de/driver.rs @@ -1,7 +1,7 @@ +use std::marker::PhantomData; use std::mem::ManuallyDrop; use crate::de::{Deserialize, DeserializerState, SinkHandle}; -use crate::descriptors::Descriptor; use crate::error::Error; use crate::event::Event; use crate::extensions::Extensions; @@ -36,7 +36,8 @@ impl<'a> DeserializeDriver<'a> { DeserializeDriver { state: DeserializerState { extensions: Extensions::default(), - descriptor_stack: Vec::with_capacity(STACK_CAPACITY), + depth: 0, + _marker: PhantomData, }, sink_stack: ManuallyDrop::new(Vec::with_capacity(STACK_CAPACITY)), current_sink: Some(unsafe { extend_lifetime!(sink, SinkHandle<'_>) }), @@ -96,10 +97,7 @@ impl<'a> DeserializeDriver<'a> { Event::MapStart => { let current_sink = current_sink!(); current_sink.map(&self.state)?; - let descriptor = current_sink.descriptor(); - self.state - .descriptor_stack - .push(unsafe { extend_lifetime!(descriptor, &dyn Descriptor) }); + self.state.depth += 1; self.sink_stack .push((self.current_sink.take().unwrap(), Layer::Map(true))); return Ok(()); @@ -107,7 +105,7 @@ impl<'a> DeserializeDriver<'a> { Event::MapEnd => match self.sink_stack.pop() { Some((mut map_sink, Layer::Map(_))) => { map_sink.finish(&self.state)?; - self.state.descriptor_stack.pop(); + self.state.depth -= 1; self.current_sink = Some(map_sink); } _ => panic!("not inside a MapSink"), @@ -115,10 +113,7 @@ impl<'a> DeserializeDriver<'a> { Event::SeqStart => { let current_sink = current_sink!(); current_sink.seq(&self.state)?; - let descriptor = current_sink.descriptor(); - self.state - .descriptor_stack - .push(unsafe { extend_lifetime!(descriptor, &dyn Descriptor) }); + self.state.depth += 1; self.sink_stack .push((self.current_sink.take().unwrap(), Layer::Seq)); return Ok(()); @@ -126,7 +121,7 @@ impl<'a> DeserializeDriver<'a> { Event::SeqEnd => match self.sink_stack.pop() { Some((mut seq_sink, Layer::Seq)) => { seq_sink.finish(&self.state)?; - self.state.descriptor_stack.pop(); + self.state.depth -= 1; self.current_sink = Some(seq_sink); } _ => panic!("not inside a SeqSink"), diff --git a/deser/src/de/impls.rs b/deser/src/de/impls.rs index 014365c..c596769 100644 --- a/deser/src/de/impls.rs +++ b/deser/src/de/impls.rs @@ -1,10 +1,10 @@ +use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::BuildHasher; use std::hash::Hash; use std::mem::{take, MaybeUninit}; use crate::de::{Deserialize, DeserializerState, OwnedSink, Sink, SinkHandle}; -use crate::descriptors::{Descriptor, NamedDescriptor, UnorderedNamedDescriptor}; use crate::error::{Error, ErrorKind}; use crate::event::Atom; @@ -21,11 +21,6 @@ macro_rules! deserialize { } impl Sink for SlotWrapper<()> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "null" }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Null => { @@ -35,15 +30,14 @@ impl Sink for SlotWrapper<()> { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("null") + } } deserialize!(()); impl Sink for SlotWrapper { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bool" }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Bool(value) => { @@ -53,15 +47,14 @@ impl Sink for SlotWrapper { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("bool") + } } deserialize!(bool); impl Sink for SlotWrapper { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "string" }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Str(value) => { @@ -71,19 +64,16 @@ impl Sink for SlotWrapper { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("string") + } } deserialize!(String); macro_rules! int_sink { ($ty:ty) => { impl Sink for SlotWrapper<$ty> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { - name: stringify!($ty), - }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::U64(value) => { @@ -113,6 +103,10 @@ macro_rules! int_sink { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed(stringify!($ty)) + } } }; } @@ -149,11 +143,6 @@ int_sink!(usize); deserialize!(usize); impl Sink for SlotWrapper { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "char" }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Char(value) => { @@ -173,19 +162,16 @@ impl Sink for SlotWrapper { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("char") + } } deserialize!(char); macro_rules! float_sink { ($ty:ty) => { impl Sink for SlotWrapper<$ty> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { - name: stringify!($ty), - }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::U64(value) => { @@ -203,6 +189,10 @@ macro_rules! float_sink { other => self.unexpected_atom(other, state), } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("float") + } } }; } @@ -231,16 +221,6 @@ impl Deserialize for Vec { } impl<'a, T: Deserialize> Sink for VecSink<'a, T> { - fn descriptor(&self) -> &dyn Descriptor { - static SLICE_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "vec" }; - static BYTES_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bytes" }; - if unsafe { T::__private_is_bytes() } { - &BYTES_DESCRIPTOR - } else { - &SLICE_DESCRIPTOR - } - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Bytes(value) => unsafe { @@ -275,6 +255,10 @@ impl Deserialize for Vec { } Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("sequence") + } } SinkHandle::boxed(VecSink { @@ -315,12 +299,6 @@ where K: Ord + Deserialize, V: Deserialize, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = - UnorderedNamedDescriptor { name: "map" }; - &DESCRIPTOR - } - fn map(&mut self, _state: &DeserializerState) -> Result<(), Error> { Ok(()) } @@ -339,6 +317,10 @@ where *self.slot = Some(take(&mut self.map)); Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("map") + } } SinkHandle::boxed(MapSink { @@ -382,12 +364,6 @@ where V: Deserialize, H: BuildHasher + Default, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = - UnorderedNamedDescriptor { name: "map" }; - &DESCRIPTOR - } - fn next_key(&mut self, _state: &DeserializerState) -> Result { self.flush(); Ok(Deserialize::deserialize_into(&mut self.key)) @@ -402,6 +378,10 @@ where *self.slot = Some(take(&mut self.map)); Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("map") + } } SinkHandle::boxed(MapSink { @@ -430,12 +410,6 @@ impl Deserialize for BTreeSet { } impl<'a, T: Deserialize + Ord> Sink for BTreeSetSink<'a, T> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = - UnorderedNamedDescriptor { name: "BTreeSet" }; - &DESCRIPTOR - } - fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> { Ok(()) } @@ -450,6 +424,10 @@ impl Deserialize for BTreeSet { *self.slot = Some(take(&mut self.set)); Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("set") + } } SinkHandle::boxed(BTreeSetSink { @@ -489,12 +467,6 @@ where T: Hash + Eq + Deserialize, H: BuildHasher + Default, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = - UnorderedNamedDescriptor { name: "HashSet" }; - &DESCRIPTOR - } - fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> { Ok(()) } @@ -509,6 +481,10 @@ where *self.slot = Some(take(&mut self.set)); Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("set") + } } SinkHandle::boxed(HashSetSink { @@ -565,8 +541,8 @@ impl<'a> Sink for NullIgnoringSink<'a> { self.sink.next_value(state) } - fn descriptor(&self) -> &dyn Descriptor { - self.sink.descriptor() + fn expecting(&self) -> Cow<'_, str> { + self.sink.expecting() } } @@ -586,11 +562,6 @@ macro_rules! deserialize_for_tuple { } impl<'a, $($name: Deserialize,)*> Sink for TupleSink<'a, $($name,)*> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "tuple" }; - &DESCRIPTOR - } - fn seq(&mut self, _state: &DeserializerState) -> Result<(), Error> { Ok(()) } @@ -616,6 +587,10 @@ macro_rules! deserialize_for_tuple { )*)); Ok(()) } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("tuple") + } } SinkHandle::boxed(TupleSink { @@ -673,11 +648,6 @@ impl Deserialize for [T; N] { } impl<'a, T: Deserialize + 'a, const N: usize> Sink for ArraySink<'a, T, N> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "array" }; - &DESCRIPTOR - } - fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> { match atom { Atom::Bytes(value) => { @@ -748,6 +718,10 @@ impl Deserialize for [T; N] { Ok(()) } } + + fn expecting(&self) -> Cow<'_, str> { + Cow::Borrowed("array") + } } SinkHandle::boxed(ArraySink { @@ -802,11 +776,7 @@ impl Deserialize for Box { Ok(()) } - fn descriptor(&self) -> &dyn Descriptor { - self.sink.borrow().descriptor() - } - - fn expecting(&self) -> std::borrow::Cow<'_, str> { + fn expecting(&self) -> Cow<'_, str> { self.sink.borrow().expecting() } } diff --git a/deser/src/de/mod.rs b/deser/src/de/mod.rs index 935a3bc..6f49d35 100644 --- a/deser/src/de/mod.rs +++ b/deser/src/de/mod.rs @@ -194,9 +194,9 @@ use std::borrow::Cow; use std::cell::{Ref, RefMut}; use std::fmt; +use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; -use crate::descriptors::{Descriptor, NullDescriptor}; use crate::error::{Error, ErrorKind}; use crate::event::Atom; @@ -279,7 +279,8 @@ impl<'a> SinkHandle<'a> { /// Gives access to the deserializer state. pub struct DeserializerState<'a> { extensions: Extensions, - descriptor_stack: Vec<&'a dyn Descriptor>, + depth: usize, + _marker: PhantomData<&'a ()>, } impl<'a> DeserializerState<'a> { @@ -295,14 +296,7 @@ impl<'a> DeserializerState<'a> { /// Returns the current recursion depth. pub fn depth(&self) -> usize { - self.descriptor_stack.len() - } - - /// Returns the topmost descriptor. - /// - /// This descriptor always points to a container as the descriptor. - pub fn top_descriptor(&self) -> Option<&dyn Descriptor> { - self.descriptor_stack.last().copied() + self.depth } } @@ -435,15 +429,10 @@ pub trait Sink { Ok(()) } - /// Returns a descriptor for this type. - fn descriptor(&self) -> &dyn Descriptor { - &NullDescriptor - } - /// Utility method to return an expectation message that is used in error messages. /// - /// The default implementation returns the type name of the descriptor if available. + /// The default implementation returns "compatible type". fn expecting(&self) -> Cow<'_, str> { - Cow::Borrowed(self.descriptor().name().unwrap_or("compatible type")) + Cow::Borrowed("compatible type") } } diff --git a/deser/src/descriptors.rs b/deser/src/descriptors.rs deleted file mode 100644 index 58660f2..0000000 --- a/deser/src/descriptors.rs +++ /dev/null @@ -1,85 +0,0 @@ -/// The default null descriptor. -pub(crate) struct NullDescriptor; - -/// A primitive descriptor with just a name. -pub(crate) struct NamedDescriptor { - pub(crate) name: &'static str, -} - -/// A number descriptor provides additional information about a number type. -pub(crate) struct NumberDescriptor { - pub(crate) name: &'static str, - pub(crate) precision: usize, -} - -/// A descriptor that is always unordered. -pub(crate) struct UnorderedNamedDescriptor { - pub(crate) name: &'static str, -} - -/// A descriptor provides auxiliary type information. -/// -/// Many types upon serialization coerce their value into a common atomic -/// value which is native to the `deser` data model. This causes challenges -/// when a serializer needs to tell the difference between the original values. -/// For instance a serializer might be interested in being able to tell a -/// `u8` from a `u64` despite the fact that both are represented equally. -/// -/// During serialization descriptors are generally created, for the deserialization -/// system descriptors are only used when entering into a nested structure -/// such as a map, struct or sequence. -pub trait Descriptor { - /// Returns a descriptive name for a type if such a name is available. - fn name(&self) -> Option<&str> { - None - } - - /// Returns the precision in bits of the value. - /// - /// This is normally set for numbers and returns the natural bit count of - /// the source information. For instancen a `u32` will return `Some(32)` - /// from this method. - fn precision(&self) -> Option { - None - } - - /// Returns information about this value's ordering characteristic. - /// - /// Things that are naturally unordered return `true` here. For instance - /// a `HashSet` returns `true` here. - fn unordered(&self) -> bool { - false - } -} - -impl Descriptor for NullDescriptor {} - -impl Descriptor for NamedDescriptor { - fn name(&self) -> Option<&str> { - Some(self.name) - } -} - -impl Descriptor for NumberDescriptor { - fn name(&self) -> Option<&str> { - Some(self.name) - } - - fn precision(&self) -> Option { - if self.precision > 0 { - Some(self.precision) - } else { - None - } - } -} - -impl Descriptor for UnorderedNamedDescriptor { - fn name(&self) -> Option<&str> { - Some(self.name) - } - - fn unordered(&self) -> bool { - true - } -} diff --git a/deser/src/lib.rs b/deser/src/lib.rs index f18959b..19fe14d 100644 --- a/deser/src/lib.rs +++ b/deser/src/lib.rs @@ -47,10 +47,8 @@ pub mod de; mod error; pub mod ser; -mod descriptors; mod extensions; -pub use self::descriptors::Descriptor; pub use self::error::{Error, ErrorKind}; pub use self::event::{Atom, Event}; diff --git a/deser/src/ser/driver.rs b/deser/src/ser/driver.rs index c420421..ce8f7a4 100644 --- a/deser/src/ser/driver.rs +++ b/deser/src/ser/driver.rs @@ -1,11 +1,12 @@ use std::borrow::Cow; +use std::marker::PhantomData; use std::mem::ManuallyDrop; use std::ops::Deref; use crate::error::Error; use crate::extensions::Extensions; use crate::ser::{Chunk, SerializerState}; -use crate::{Descriptor, Event, Serialize}; +use crate::{Event, Serialize}; use super::{MapEmitter, SeqEmitter, SerializeHandle, StructEmitter}; @@ -19,7 +20,7 @@ pub struct SerializeDriver<'a> { state_stack: Vec, serializable_stack: ManuallyDrop>, emitter_stack: ManuallyDrop>, - next_event: Option<(Event<'a>, &'a dyn Descriptor)>, + next_event: Option>, } // We like to hold on to Cow<'_, str> in addition to a SerializeHandle @@ -82,7 +83,8 @@ impl<'a> SerializeDriver<'a> { SerializeDriver { state: SerializerState { extensions: Extensions::default(), - descriptor_stack: Vec::with_capacity(STACK_CAPACITY), + depth: 0, + _marker: PhantomData, }, emitter_stack: ManuallyDrop::new(Vec::with_capacity(STACK_CAPACITY)), serializable_stack: ManuallyDrop::new({ @@ -110,12 +112,9 @@ impl<'a> SerializeDriver<'a> { /// /// The driver will panic if the data fed from the serializer is malformed. #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Result, Error> { + pub fn next(&mut self) -> Result, Error> { self.advance()?; - Ok(self - .next_event - .take() - .map(|(event, descriptor)| (event, descriptor, &self.state))) + Ok(self.next_event.take().map(|event| (event, &self.state))) } fn advance(&mut self) -> Result<(), Error> { @@ -204,54 +203,40 @@ impl<'a> SerializeDriver<'a> { let serializable = self.serializable_stack.last().unwrap(); match unsafe { extend_lifetime!(serializable.serialize(&self.state)?, Chunk) } { Chunk::Atom(atom) => { - self.next_event = Some((Event::Atom(atom), unsafe { - extend_lifetime!(serializable.descriptor(), &dyn Descriptor) - })); + self.next_event = Some(Event::Atom(atom)); *state = DriverState::FinishSerialize; return Ok(()); } Chunk::Struct(emitter) => { - let descriptor = unsafe { - extend_lifetime!(serializable.descriptor(), &dyn Descriptor) - }; - self.next_event = Some((Event::MapStart, descriptor)); + self.next_event = Some(Event::MapStart); self.emitter_stack.push(Emitter::Struct(emitter)); *state = DriverState::StructEmitterAdvance; - self.state.descriptor_stack.push(descriptor); + self.state.depth += 1; return Ok(()); } Chunk::Map(emitter) => { - let descriptor = unsafe { - extend_lifetime!(serializable.descriptor(), &dyn Descriptor) - }; - self.next_event = Some((Event::MapStart, descriptor)); + self.next_event = Some(Event::MapStart); self.emitter_stack.push(Emitter::Map(emitter)); *state = DriverState::MapEmitterNextKey; - self.state.descriptor_stack.push(descriptor); + self.state.depth += 1; return Ok(()); } Chunk::Seq(emitter) => { - let descriptor = unsafe { - extend_lifetime!(serializable.descriptor(), &dyn Descriptor) - }; - self.next_event = Some((Event::SeqStart, descriptor)); + self.next_event = Some(Event::SeqStart); self.emitter_stack.push(Emitter::Seq(emitter)); *state = DriverState::SeqEmitterAdvance; - self.state.descriptor_stack.push(descriptor); + self.state.depth += 1; return Ok(()); } } } DriverState::PopEmitter => { - let descriptor = self.state.descriptor_stack.pop().unwrap(); + self.state.depth -= 1; *state = DriverState::FinishSerialize; - self.next_event = Some(( - match self.emitter_stack.pop().unwrap() { - Emitter::Seq(_) => Event::SeqEnd, - Emitter::Map(_) | Emitter::Struct(_) => Event::MapEnd, - }, - descriptor, - )); + self.next_event = Some(match self.emitter_stack.pop().unwrap() { + Emitter::Seq(_) => Event::SeqEnd, + Emitter::Map(_) | Emitter::Struct(_) => Event::MapEnd, + }); return Ok(()); } DriverState::FinishSerialize => { @@ -272,7 +257,7 @@ fn test_seq_emitting() { let mut driver = SerializeDriver::new(&vec); let mut events = Vec::new(); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { events.push(event.to_static()); } @@ -301,7 +286,7 @@ fn test_map_emitting() { let mut driver = SerializeDriver::new(&map); let mut events = Vec::new(); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { events.push(event.to_static()); } diff --git a/deser/src/ser/impls.rs b/deser/src/ser/impls.rs index 18e6642..156ed7b 100644 --- a/deser/src/ser/impls.rs +++ b/deser/src/ser/impls.rs @@ -2,28 +2,17 @@ use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::BuildHasher; -use crate::descriptors::{Descriptor, NamedDescriptor, NumberDescriptor, UnorderedNamedDescriptor}; use crate::error::Error; use crate::event::Atom; use crate::ser::{Chunk, MapEmitter, SeqEmitter, Serialize, SerializeHandle, SerializerState}; impl Serialize for bool { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bool" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Bool(*self))) } } impl Serialize for () { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "null" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Null)) } @@ -34,14 +23,6 @@ impl Serialize for () { } impl Serialize for u8 { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NumberDescriptor = NumberDescriptor { - name: "u8", - precision: 8, - }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::U64(*self as u64))) } @@ -52,11 +33,6 @@ impl Serialize for u8 { } impl Serialize for char { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "char" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Char(*self))) } @@ -65,14 +41,6 @@ impl Serialize for char { macro_rules! serialize_int { ($ty:ty, $atom:ident) => { impl Serialize for $ty { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NumberDescriptor = NumberDescriptor { - name: stringify!($ty), - precision: std::mem::size_of::<$ty>() * 8, - }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::$atom(*self as _))) } @@ -93,33 +61,18 @@ serialize_int!(f32, F64); serialize_int!(f64, F64); impl Serialize for String { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "String" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Str(self.as_str().into()))) } } impl<'a> Serialize for &'a str { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "str" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Str((*self).into()))) } } impl<'a> Serialize for Cow<'a, str> { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "str" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Atom(Atom::Str(Cow::Borrowed(self)))) } @@ -129,16 +82,6 @@ impl Serialize for Vec where T: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static SLICE_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "Vec" }; - static BYTES_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "ByteVec" }; - if T::__private_slice_as_bytes(self).is_some() { - &BYTES_DESCRIPTOR - } else { - &SLICE_DESCRIPTOR - } - } - fn serialize(&self, _state: &SerializerState) -> Result { if let Some(bytes) = T::__private_slice_as_bytes(&self[..]) { Ok(Chunk::Atom(Atom::Bytes(bytes))) @@ -152,16 +95,6 @@ impl<'a, T> Serialize for &'a [T] where T: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static SLICE_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "slice" }; - static BYTES_DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "bytes" }; - if T::__private_slice_as_bytes(self).is_some() { - &BYTES_DESCRIPTOR - } else { - &SLICE_DESCRIPTOR - } - } - fn serialize(&self, _state: &SerializerState) -> Result { if let Some(bytes) = T::__private_slice_as_bytes(self) { Ok(Chunk::Atom(Atom::Bytes(bytes))) @@ -184,11 +117,6 @@ where K: Serialize, V: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "BTreeMap" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { struct Emitter<'a, K, V>(std::collections::btree_map::Iter<'a, K, V>, Option<&'a V>); @@ -222,11 +150,6 @@ where V: Serialize, H: BuildHasher, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = UnorderedNamedDescriptor { name: "HashMap" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { struct Emitter<'a, K, V>(std::collections::hash_map::Iter<'a, K, V>, Option<&'a V>); @@ -258,11 +181,6 @@ impl Serialize for BTreeSet where T: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "BTreeSet" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { struct Emitter<'a, T>(std::collections::btree_set::Iter<'a, T>); @@ -283,11 +201,6 @@ impl Serialize for HashSet where T: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: UnorderedNamedDescriptor = UnorderedNamedDescriptor { name: "HashSet" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { struct Emitter<'a, T>(std::collections::hash_set::Iter<'a, T>); @@ -308,11 +221,6 @@ impl Serialize for Option where T: Serialize, { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "optional" }; - &DESCRIPTOR - } - fn is_optional(&self) -> bool { self.is_none() } @@ -329,11 +237,6 @@ macro_rules! serialize_for_tuple { () => (); ($($name:ident,)+) => ( impl<$($name: Serialize),*> Serialize for ($($name,)*) { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "tuple" }; - &DESCRIPTOR - } - #[allow(non_snake_case)] fn serialize(&self, _state: &SerializerState) -> Result { struct TupleSeqEmitter<'a, $($name,)*> { @@ -377,11 +280,6 @@ macro_rules! serialize_for_tuple_peel { serialize_for_tuple! { T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, } impl Serialize for [T; N] { - fn descriptor(&self) -> &dyn Descriptor { - static DESCRIPTOR: NamedDescriptor = NamedDescriptor { name: "array" }; - &DESCRIPTOR - } - fn serialize(&self, _state: &SerializerState) -> Result { if let Some(bytes) = T::__private_slice_as_bytes(self) { Ok(Chunk::Atom(Atom::Bytes(bytes))) diff --git a/deser/src/ser/mod.rs b/deser/src/ser/mod.rs index bb219c1..aa6692b 100644 --- a/deser/src/ser/mod.rs +++ b/deser/src/ser/mod.rs @@ -16,7 +16,7 @@ //! # fn do_it() -> Result<(), deser::Error> { //! let serializable = vec!["foo", "bar", "baz"]; //! let mut driver = SerializeDriver::new(&serializable); -//! while let Some((event, descriptor, state)) = driver.next()? { +//! while let Some((event, state)) = driver.next()? { //! // serialize each event for the target format such as JSON //! } //! # Ok(()) }; do_it().unwrap(); @@ -28,32 +28,14 @@ //! //! Primitive values such as integers are trivial to serialize as you just //! directly return the right type of [`Chunk`] from the serialization method. -//! In this example we also provide an optional [`Descriptor`] which can help -//! serializers make better decisions. //! //! ```rust //! use deser::ser::{Serialize, SerializerState, Chunk}; -//! use deser::{Atom, Descriptor, Error}; +//! use deser::{Atom, Error}; //! //! struct MyInt(u32); //! -//! struct MyIntDescriptor; -//! -//! impl Descriptor for MyIntDescriptor { -//! fn name(&self) -> Option<&str> { -//! Some("MyInt") -//! } -//! -//! fn precision(&self) -> Option { -//! Some(32) -//! } -//! } -//! //! impl Serialize for MyInt { -//! fn descriptor(&self) -> &dyn Descriptor { -//! &MyIntDescriptor -//! } -//! //! fn serialize(&self, state: &SerializerState) -> Result { //! // one can also just do `self.0.serialize(state)` //! Ok(Chunk::Atom(Atom::U64(self.0 as u64))) @@ -108,9 +90,9 @@ use std::borrow::Cow; use std::cell::{Ref, RefMut}; use std::fmt; +use std::marker::PhantomData; use std::ops::Deref; -use crate::descriptors::{Descriptor, NullDescriptor}; use crate::error::Error; use crate::extensions::Extensions; @@ -167,37 +149,14 @@ impl<'a> SerializeHandle<'a> { /// the serializable types as the serializer. pub struct SerializerState<'a> { extensions: Extensions, - descriptor_stack: Vec<&'a dyn Descriptor>, + depth: usize, + _marker: PhantomData<&'a ()>, } impl<'a> fmt::Debug for SerializerState<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - struct Stack<'a>(&'a [&'a dyn Descriptor]); - struct Entry<'a>(&'a dyn Descriptor); - - impl<'a> fmt::Debug for Entry<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Layer") - .field("type_name", &self.0.name()) - .field("precision", &self.0.precision()) - .field("unordered", &self.0.unordered()) - .finish() - } - } - - impl<'a> fmt::Debug for Stack<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut l = f.debug_list(); - for item in self.0.iter() { - l.entry(&Entry(*item)); - } - l.finish() - } - } - f.debug_struct("SerializerState") .field("extensions", &self.extensions) - .field("stack", &Stack(&self.descriptor_stack)) .finish() } } @@ -215,15 +174,7 @@ impl<'a> SerializerState<'a> { /// Returns the current recursion depth. pub fn depth(&self) -> usize { - self.descriptor_stack.len() - } - - /// Returns the topmost descriptor. - /// - /// This descriptor always points to a container as the descriptor of a value itself - /// will always be passed to the callback explicitly. - pub fn top_descriptor(&self) -> Option<&dyn Descriptor> { - self.descriptor_stack.last().copied() + self.depth } } @@ -266,14 +217,12 @@ pub trait SeqEmitter { /// A data structure that can be serialized into any data format supported by Deser. /// -/// This trait provides two things: +/// The most important methods are: /// -/// * [`descriptor`](Self::descriptor) returns a reference to the closest descriptor -/// of this value. The descriptor provides auxiliary information about the value -/// that the serialization system does not expose. /// * [`serialize`](Self::serialize) serializes the value into a [`Chunk`]. For /// compound values like lists or similar, the piece contains a boxed emitter /// which can be further processed to walk the embedded compound value. +/// * [`finish`](Self::finish) is invoked after the serialization is done. pub trait Serialize { /// Serializes this serializable. fn serialize(&self, state: &SerializerState) -> Result; @@ -298,11 +247,6 @@ pub trait Serialize { false } - /// Returns the descriptor of this serializable if it exists. - fn descriptor(&self) -> &dyn Descriptor { - &NullDescriptor - } - /// Hidden internal trait method to allow specializations of bytes. /// /// This method is used by `u8` and `Vec` / `&[T]` to achieve special @@ -325,7 +269,7 @@ fn test_serialize() { m.insert(false, vec![]); let mut driver = SerializeDriver::new(&m); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { v.push(format!("{:?}", event)); } diff --git a/deser/tests/test_custom_map.rs b/deser/tests/test_custom_map.rs index 0b88568..0015097 100644 --- a/deser/tests/test_custom_map.rs +++ b/deser/tests/test_custom_map.rs @@ -44,7 +44,7 @@ fn test_as_string_map() { map }); let mut driver = SerializeDriver::new(&flags); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { events.push(format!("{:?}", event)); } diff --git a/deser/tests/test_ser.rs b/deser/tests/test_ser.rs index a990f08..f25f7d7 100644 --- a/deser/tests/test_ser.rs +++ b/deser/tests/test_ser.rs @@ -7,7 +7,7 @@ use deser::{Atom, Event, Serialize}; fn capture_events(s: &dyn Serialize) -> Vec> { let mut events = Vec::new(); let mut driver = SerializeDriver::new(s); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { events.push(event.to_static()); } events diff --git a/deser/tests/test_ser_derive.rs b/deser/tests/test_ser_derive.rs index d20ea9d..223bfcd 100644 --- a/deser/tests/test_ser_derive.rs +++ b/deser/tests/test_ser_derive.rs @@ -4,7 +4,7 @@ use deser::{Event, Serialize}; fn serialize(value: &T) -> Vec> { let mut rv = Vec::new(); let mut driver = SerializeDriver::new(value); - while let Some((event, _, _)) = driver.next().unwrap() { + while let Some((event, _)) = driver.next().unwrap() { rv.push(event.to_static()); } rv diff --git a/examples/manual-struct/src/main.rs b/examples/manual-struct/src/main.rs index 6423b01..83795b6 100644 --- a/examples/manual-struct/src/main.rs +++ b/examples/manual-struct/src/main.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use deser::de::{DeserializeDriver, DeserializerState, Sink, SinkHandle}; use deser::ser::{Chunk, SerializeHandle, SerializerState, StructEmitter}; -use deser::{Descriptor, Deserialize, Error, ErrorKind, Event, Serialize}; +use deser::{Deserialize, Error, ErrorKind, Event, Serialize}; use deser_debug::ToDebug; pub struct User { @@ -11,10 +11,6 @@ pub struct User { } impl Serialize for User { - fn descriptor(&self) -> &dyn Descriptor { - &UserDescriptor - } - fn serialize(&self, _state: &SerializerState) -> Result { Ok(Chunk::Struct(Box::new(UserEmitter { user: self, @@ -23,14 +19,6 @@ impl Serialize for User { } } -struct UserDescriptor; - -impl Descriptor for UserDescriptor { - fn name(&self) -> Option<&str> { - Some("User") - } -} - struct UserEmitter<'a> { user: &'a User, index: usize, @@ -73,10 +61,6 @@ struct UserSink<'a> { } impl<'a> Sink for UserSink<'a> { - fn descriptor(&self) -> &dyn Descriptor { - &UserDescriptor - } - fn map(&mut self, _state: &DeserializerState) -> Result<(), Error> { Ok(()) }