use self::ErrorImpl::ShortCircuit; use crate::error::Error; use crate::sealed; use alloc::boxed::Box; use alloc::string::{String, ToString}; use core::fmt::{self, Debug, Display}; use serde::ser::{ SerializeMap as _, SerializeSeq as _, SerializeStruct as _, SerializeStructVariant as _, SerializeTuple as _, SerializeTupleStruct as _, SerializeTupleVariant as _, }; // TRAITS ////////////////////////////////////////////////////////////////////// /// An object-safe equivalent of Serde's `Serialize` trait. /// /// Any implementation of Serde's `Serialize` converts seamlessly to a /// `&dyn erased_serde::Serialize` or `Box` trait /// object. /// /// ```rust /// use erased_serde::{Serialize, Serializer}; /// use std::collections::BTreeMap as Map; /// use std::io; /// /// fn main() { /// // Construct some serializers. /// let json = &mut serde_json::Serializer::new(io::stdout()); /// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); /// /// // The values in this map are boxed trait objects. Ordinarily this would not /// // be possible with serde::Serializer because of object safety, but type /// // erasure makes it possible with erased_serde::Serializer. /// let mut formats: Map<&str, Box> = Map::new(); /// formats.insert("json", Box::new(::erase(json))); /// formats.insert("cbor", Box::new(::erase(cbor))); /// /// // These are boxed trait objects as well. Same thing here - type erasure /// // makes this possible. /// let mut values: Map<&str, Box> = Map::new(); /// values.insert("vec", Box::new(vec!["a", "b"])); /// values.insert("int", Box::new(65536)); /// /// // Pick a Serializer out of the formats map. /// let format = formats.get_mut("json").unwrap(); /// /// // Pick a Serialize out of the values map. /// let value = values.get("vec").unwrap(); /// /// // This line prints `["a","b"]` to stdout. /// value.erased_serialize(format).unwrap(); /// } /// ``` /// /// This trait is sealed and can only be implemented via a `serde::Serialize` /// impl. #[cfg_attr( not(no_diagnostic_namespace), diagnostic::on_unimplemented( message = "the trait bound `{Self}: serde::Serialize` is not satisfied", label = "the trait `serde::Serialize` is not implemented for `{Self}`, so it does not implement `erased_serde::Serialize`", ) )] pub trait Serialize: sealed::serialize::Sealed { fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error>; #[doc(hidden)] fn do_erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), ErrorImpl>; } /// An object-safe equivalent of Serde's `Serializer` trait. /// /// Any implementation of Serde's `Serializer` can be converted to a /// `&dyn erased_serde::Serializer` or `Box` trait /// object using `erased_serde::Serializer::erase`. /// /// ```rust /// use erased_serde::{Serialize, Serializer}; /// use std::collections::BTreeMap as Map; /// use std::io; /// /// fn main() { /// // Construct some serializers. /// let json = &mut serde_json::Serializer::new(io::stdout()); /// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); /// /// // The values in this map are boxed trait objects. Ordinarily this would not /// // be possible with serde::Serializer because of object safety, but type /// // erasure makes it possible with erased_serde::Serializer. /// let mut formats: Map<&str, Box> = Map::new(); /// formats.insert("json", Box::new(::erase(json))); /// formats.insert("cbor", Box::new(::erase(cbor))); /// /// // These are boxed trait objects as well. Same thing here - type erasure /// // makes this possible. /// let mut values: Map<&str, Box> = Map::new(); /// values.insert("vec", Box::new(vec!["a", "b"])); /// values.insert("int", Box::new(65536)); /// /// // Pick a Serializer out of the formats map. /// let format = formats.get_mut("json").unwrap(); /// /// // Pick a Serialize out of the values map. /// let value = values.get("vec").unwrap(); /// /// // This line prints `["a","b"]` to stdout. /// value.erased_serialize(format).unwrap(); /// } /// ``` /// /// This trait is sealed and can only be implemented via a `serde::Serializer` /// impl. pub trait Serializer: sealed::serializer::Sealed { fn erased_serialize_bool(&mut self, v: bool); fn erased_serialize_i8(&mut self, v: i8); fn erased_serialize_i16(&mut self, v: i16); fn erased_serialize_i32(&mut self, v: i32); fn erased_serialize_i64(&mut self, v: i64); fn erased_serialize_i128(&mut self, v: i128); fn erased_serialize_u8(&mut self, v: u8); fn erased_serialize_u16(&mut self, v: u16); fn erased_serialize_u32(&mut self, v: u32); fn erased_serialize_u64(&mut self, v: u64); fn erased_serialize_u128(&mut self, v: u128); fn erased_serialize_f32(&mut self, v: f32); fn erased_serialize_f64(&mut self, v: f64); fn erased_serialize_char(&mut self, v: char); fn erased_serialize_str(&mut self, v: &str); fn erased_serialize_bytes(&mut self, v: &[u8]); fn erased_serialize_none(&mut self); fn erased_serialize_some(&mut self, value: &dyn Serialize); fn erased_serialize_unit(&mut self); fn erased_serialize_unit_struct(&mut self, name: &'static str); fn erased_serialize_unit_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, ); fn erased_serialize_newtype_struct(&mut self, name: &'static str, value: &dyn Serialize); fn erased_serialize_newtype_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, value: &dyn Serialize, ); fn erased_serialize_seq( &mut self, len: Option, ) -> Result<&mut dyn SerializeSeq, ErrorImpl>; fn erased_serialize_tuple(&mut self, len: usize) -> Result<&mut dyn SerializeTuple, ErrorImpl>; fn erased_serialize_tuple_struct( &mut self, name: &'static str, len: usize, ) -> Result<&mut dyn SerializeTupleStruct, ErrorImpl>; fn erased_serialize_tuple_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result<&mut dyn SerializeTupleVariant, ErrorImpl>; fn erased_serialize_map( &mut self, len: Option, ) -> Result<&mut dyn SerializeMap, ErrorImpl>; fn erased_serialize_struct( &mut self, name: &'static str, len: usize, ) -> Result<&mut dyn SerializeStruct, ErrorImpl>; fn erased_serialize_struct_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result<&mut dyn SerializeStructVariant, ErrorImpl>; fn erased_is_human_readable(&self) -> bool; #[doc(hidden)] fn erased_display_error(&self) -> &dyn Display; } impl dyn Serializer { /// Convert any Serde `Serializer` to a trait object. /// /// ```rust /// use erased_serde::{Serialize, Serializer}; /// use std::collections::BTreeMap as Map; /// use std::io; /// /// fn main() { /// // Construct some serializers. /// let json = &mut serde_json::Serializer::new(io::stdout()); /// let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout())); /// /// // The values in this map are boxed trait objects. Ordinarily this would not /// // be possible with serde::Serializer because of object safety, but type /// // erasure makes it possible with erased_serde::Serializer. /// let mut formats: Map<&str, Box> = Map::new(); /// formats.insert("json", Box::new(::erase(json))); /// formats.insert("cbor", Box::new(::erase(cbor))); /// /// // These are boxed trait objects as well. Same thing here - type erasure /// // makes this possible. /// let mut values: Map<&str, Box> = Map::new(); /// values.insert("vec", Box::new(vec!["a", "b"])); /// values.insert("int", Box::new(65536)); /// /// // Pick a Serializer out of the formats map. /// let format = formats.get_mut("json").unwrap(); /// /// // Pick a Serialize out of the values map. /// let value = values.get("vec").unwrap(); /// /// // This line prints `["a","b"]` to stdout. /// value.erased_serialize(format).unwrap(); /// } /// ``` pub fn erase(serializer: S) -> impl Serializer where S: serde::Serializer, { erase::Serializer::new(serializer) } } // IMPL ERASED SERDE FOR SERDE ///////////////////////////////////////////////// impl Serialize for T where T: ?Sized + serde::Serialize, { fn erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), Error> { match self.do_erased_serialize(serializer) { Ok(()) => Ok(()), Err(ShortCircuit) => Err(serde::ser::Error::custom(serializer.erased_display_error())), Err(ErrorImpl::Custom(msg)) => Err(serde::ser::Error::custom(msg)), } } fn do_erased_serialize(&self, serializer: &mut dyn Serializer) -> Result<(), ErrorImpl> { self.serialize(MakeSerializer(serializer)) } } impl sealed::serialize::Sealed for T where T: ?Sized + serde::Serialize {} mod erase { use core::mem; pub enum Serializer where S: serde::Serializer, { Ready(S), Seq(S::SerializeSeq), Tuple(S::SerializeTuple), TupleStruct(S::SerializeTupleStruct), TupleVariant(S::SerializeTupleVariant), Map(S::SerializeMap), Struct(S::SerializeStruct), StructVariant(S::SerializeStructVariant), Error(S::Error), Complete(S::Ok), Unusable, } impl Serializer where S: serde::Serializer, { pub(crate) fn new(serializer: S) -> Self { Serializer::Ready(serializer) } pub(crate) fn take(&mut self) -> Self { mem::replace(self, Serializer::Unusable) } pub(crate) fn take_serializer(&mut self) -> S { match self.take() { Serializer::Ready(serializer) => serializer, _ => unreachable!(), } } } } impl Serializer for erase::Serializer where T: serde::Serializer, { fn erased_serialize_bool(&mut self, v: bool) { *self = match self.take_serializer().serialize_bool(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_i8(&mut self, v: i8) { *self = match self.take_serializer().serialize_i8(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_i16(&mut self, v: i16) { *self = match self.take_serializer().serialize_i16(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_i32(&mut self, v: i32) { *self = match self.take_serializer().serialize_i32(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_i64(&mut self, v: i64) { *self = match self.take_serializer().serialize_i64(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_i128(&mut self, v: i128) { *self = match self.take_serializer().serialize_i128(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_u8(&mut self, v: u8) { *self = match self.take_serializer().serialize_u8(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_u16(&mut self, v: u16) { *self = match self.take_serializer().serialize_u16(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_u32(&mut self, v: u32) { *self = match self.take_serializer().serialize_u32(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_u64(&mut self, v: u64) { *self = match self.take_serializer().serialize_u64(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_u128(&mut self, v: u128) { *self = match self.take_serializer().serialize_u128(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_f32(&mut self, v: f32) { *self = match self.take_serializer().serialize_f32(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_f64(&mut self, v: f64) { *self = match self.take_serializer().serialize_f64(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_char(&mut self, v: char) { *self = match self.take_serializer().serialize_char(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_str(&mut self, v: &str) { *self = match self.take_serializer().serialize_str(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_bytes(&mut self, v: &[u8]) { *self = match self.take_serializer().serialize_bytes(v) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_none(&mut self) { *self = match self.take_serializer().serialize_none() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_some(&mut self, value: &dyn Serialize) { *self = match self.take_serializer().serialize_some(value) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_unit(&mut self) { *self = match self.take_serializer().serialize_unit() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_unit_struct(&mut self, name: &'static str) { *self = match self.take_serializer().serialize_unit_struct(name) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_unit_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, ) { *self = match self .take_serializer() .serialize_unit_variant(name, variant_index, variant) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_newtype_struct(&mut self, name: &'static str, value: &dyn Serialize) { *self = match self.take_serializer().serialize_newtype_struct(name, value) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_newtype_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, value: &dyn Serialize, ) { *self = match self.take_serializer().serialize_newtype_variant( name, variant_index, variant, value, ) { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } fn erased_serialize_seq( &mut self, len: Option, ) -> Result<&mut dyn SerializeSeq, ErrorImpl> { match self.take_serializer().serialize_seq(len) { Ok(ok) => { *self = erase::Serializer::Seq(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_tuple(&mut self, len: usize) -> Result<&mut dyn SerializeTuple, ErrorImpl> { match self.take_serializer().serialize_tuple(len) { Ok(ok) => { *self = erase::Serializer::Tuple(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_tuple_struct( &mut self, name: &'static str, len: usize, ) -> Result<&mut dyn SerializeTupleStruct, ErrorImpl> { match self.take_serializer().serialize_tuple_struct(name, len) { Ok(ok) => { *self = erase::Serializer::TupleStruct(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_tuple_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result<&mut dyn SerializeTupleVariant, ErrorImpl> { match self .take_serializer() .serialize_tuple_variant(name, variant_index, variant, len) { Ok(ok) => { *self = erase::Serializer::TupleVariant(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_map( &mut self, len: Option, ) -> Result<&mut dyn SerializeMap, ErrorImpl> { match self.take_serializer().serialize_map(len) { Ok(ok) => { *self = erase::Serializer::Map(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_struct( &mut self, name: &'static str, len: usize, ) -> Result<&mut dyn SerializeStruct, ErrorImpl> { match self.take_serializer().serialize_struct(name, len) { Ok(ok) => { *self = erase::Serializer::Struct(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_serialize_struct_variant( &mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result<&mut dyn SerializeStructVariant, ErrorImpl> { match self .take_serializer() .serialize_struct_variant(name, variant_index, variant, len) { Ok(ok) => { *self = erase::Serializer::StructVariant(ok); Ok(self) } Err(err) => { *self = erase::Serializer::Error(err); Err(ShortCircuit) } } } fn erased_is_human_readable(&self) -> bool { match self { erase::Serializer::Ready(serializer) => serializer.is_human_readable(), _ => unreachable!(), } } fn erased_display_error(&self) -> &dyn Display { match self { erase::Serializer::Error(err) => err, _ => unreachable!(), } } } impl sealed::serializer::Sealed for erase::Serializer where T: serde::Serializer {} pub enum ErrorImpl { ShortCircuit, Custom(Box), } impl Display for ErrorImpl { fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } impl Debug for ErrorImpl { fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } impl serde::ser::StdError for ErrorImpl {} impl serde::ser::Error for ErrorImpl { fn custom(msg: T) -> Self { ErrorImpl::Custom(Box::new(msg.to_string())) } } // IMPL SERDE FOR ERASED SERDE ///////////////////////////////////////////////// /// Serialize the given type-erased serializable value. /// /// This can be used to implement `serde::Serialize` for trait objects that have /// `erased_serde::Serialize` as a supertrait. /// /// ``` /// trait Event: erased_serde::Serialize { /// /* ... */ /// } /// /// impl<'a> serde::Serialize for dyn Event + 'a { /// fn serialize(&self, serializer: S) -> Result /// where /// S: serde::Serializer, /// { /// erased_serde::serialize(self, serializer) /// } /// } /// ``` /// /// Since this is reasonably common, the `serialize_trait_object!` macro /// generates such a Serialize impl. /// /// ``` /// use erased_serde::serialize_trait_object; /// # /// # trait Event: erased_serde::Serialize {} /// /// serialize_trait_object!(Event); /// ``` pub fn serialize(value: &T, serializer: S) -> Result where T: ?Sized + Serialize, S: serde::Serializer, { let mut erased = erase::Serializer::new(serializer); match value.do_erased_serialize(&mut erased) { Ok(()) | Err(ShortCircuit) => {} Err(ErrorImpl::Custom(msg)) => return Err(serde::ser::Error::custom(msg)), } match erased { erase::Serializer::Complete(ok) => Ok(ok), erase::Serializer::Error(err) => Err(err), _ => unreachable!(), } } serialize_trait_object!(Serialize); struct MakeSerializer(TraitObject); impl<'a> serde::Serializer for MakeSerializer<&'a mut (dyn Serializer + '_)> { type Ok = (); type Error = ErrorImpl; type SerializeSeq = MakeSerializer<&'a mut dyn SerializeSeq>; type SerializeTuple = MakeSerializer<&'a mut dyn SerializeTuple>; type SerializeTupleStruct = MakeSerializer<&'a mut dyn SerializeTupleStruct>; type SerializeTupleVariant = MakeSerializer<&'a mut dyn SerializeTupleVariant>; type SerializeMap = MakeSerializer<&'a mut dyn SerializeMap>; type SerializeStruct = MakeSerializer<&'a mut dyn SerializeStruct>; type SerializeStructVariant = MakeSerializer<&'a mut dyn SerializeStructVariant>; fn serialize_bool(self, v: bool) -> Result { self.0.erased_serialize_bool(v); Ok(()) } fn serialize_i8(self, v: i8) -> Result { self.0.erased_serialize_i8(v); Ok(()) } fn serialize_i16(self, v: i16) -> Result { self.0.erased_serialize_i16(v); Ok(()) } fn serialize_i32(self, v: i32) -> Result { self.0.erased_serialize_i32(v); Ok(()) } fn serialize_i64(self, v: i64) -> Result { self.0.erased_serialize_i64(v); Ok(()) } fn serialize_i128(self, v: i128) -> Result { self.0.erased_serialize_i128(v); Ok(()) } fn serialize_u8(self, v: u8) -> Result { self.0.erased_serialize_u8(v); Ok(()) } fn serialize_u16(self, v: u16) -> Result { self.0.erased_serialize_u16(v); Ok(()) } fn serialize_u32(self, v: u32) -> Result { self.0.erased_serialize_u32(v); Ok(()) } fn serialize_u64(self, v: u64) -> Result { self.0.erased_serialize_u64(v); Ok(()) } fn serialize_u128(self, v: u128) -> Result { self.0.erased_serialize_u128(v); Ok(()) } fn serialize_f32(self, v: f32) -> Result { self.0.erased_serialize_f32(v); Ok(()) } fn serialize_f64(self, v: f64) -> Result { self.0.erased_serialize_f64(v); Ok(()) } fn serialize_char(self, v: char) -> Result { self.0.erased_serialize_char(v); Ok(()) } fn serialize_str(self, v: &str) -> Result { self.0.erased_serialize_str(v); Ok(()) } fn serialize_bytes(self, v: &[u8]) -> Result { self.0.erased_serialize_bytes(v); Ok(()) } fn serialize_none(self) -> Result { self.0.erased_serialize_none(); Ok(()) } fn serialize_some(self, value: &T) -> Result where T: ?Sized + serde::Serialize, { self.0.erased_serialize_some(&value); Ok(()) } fn serialize_unit(self) -> Result { self.0.erased_serialize_unit(); Ok(()) } fn serialize_unit_struct(self, name: &'static str) -> Result { self.0.erased_serialize_unit_struct(name); Ok(()) } fn serialize_unit_variant( self, name: &'static str, variant_index: u32, variant: &'static str, ) -> Result { self.0 .erased_serialize_unit_variant(name, variant_index, variant); Ok(()) } fn serialize_newtype_struct( self, name: &'static str, value: &T, ) -> Result where T: ?Sized + serde::Serialize, { self.0.erased_serialize_newtype_struct(name, &value); Ok(()) } fn serialize_newtype_variant( self, name: &'static str, variant_index: u32, variant: &'static str, value: &T, ) -> Result where T: ?Sized + serde::Serialize, { self.0 .erased_serialize_newtype_variant(name, variant_index, variant, &value); Ok(()) } fn serialize_seq(self, len: Option) -> Result { self.0.erased_serialize_seq(len).map(MakeSerializer) } fn serialize_tuple(self, len: usize) -> Result { self.0.erased_serialize_tuple(len).map(MakeSerializer) } fn serialize_tuple_struct( self, name: &'static str, len: usize, ) -> Result { self.0 .erased_serialize_tuple_struct(name, len) .map(MakeSerializer) } fn serialize_tuple_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { self.0 .erased_serialize_tuple_variant(name, variant_index, variant, len) .map(MakeSerializer) } fn serialize_map(self, len: Option) -> Result { self.0.erased_serialize_map(len).map(MakeSerializer) } fn serialize_struct( self, name: &'static str, len: usize, ) -> Result { self.0 .erased_serialize_struct(name, len) .map(MakeSerializer) } fn serialize_struct_variant( self, name: &'static str, variant_index: u32, variant: &'static str, len: usize, ) -> Result { self.0 .erased_serialize_struct_variant(name, variant_index, variant, len) .map(MakeSerializer) } #[cfg(not(feature = "alloc"))] fn collect_str(self, value: &T) -> Result where T: ?Sized + Display, { unreachable!() } fn is_human_readable(&self) -> bool { self.0.erased_is_human_readable() } } pub trait SerializeSeq { fn erased_serialize_element(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeSeq for erase::Serializer where T: serde::Serializer, { fn erased_serialize_element(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Seq(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_element(value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::Seq(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeSeq for MakeSerializer<&mut dyn SerializeSeq> { type Ok = (); type Error = ErrorImpl; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_element(&value) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeTuple { fn erased_serialize_element(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeTuple for erase::Serializer where T: serde::Serializer, { fn erased_serialize_element(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Tuple(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_element(value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::Tuple(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeTuple for MakeSerializer<&mut dyn SerializeTuple> { type Ok = (); type Error = ErrorImpl; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_element(&value) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeTupleStruct { fn erased_serialize_field(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeTupleStruct for erase::Serializer where T: serde::Serializer, { fn erased_serialize_field(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::TupleStruct(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_field(value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::TupleStruct(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeTupleStruct for MakeSerializer<&mut dyn SerializeTupleStruct> { type Ok = (); type Error = ErrorImpl; fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_field(&value) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeTupleVariant { fn erased_serialize_field(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeTupleVariant for erase::Serializer where T: serde::Serializer, { fn erased_serialize_field(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::TupleVariant(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_field(value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::TupleVariant(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeTupleVariant for MakeSerializer<&mut dyn SerializeTupleVariant> { type Ok = (); type Error = ErrorImpl; fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_field(&value) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeMap { fn erased_serialize_key(&mut self, key: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_serialize_value(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl>; fn erased_serialize_entry( &mut self, key: &dyn Serialize, value: &dyn Serialize, ) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeMap for erase::Serializer where T: serde::Serializer, { fn erased_serialize_key(&mut self, key: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Map(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_key(key).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_serialize_value(&mut self, value: &dyn Serialize) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Map(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_value(value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_serialize_entry( &mut self, key: &dyn Serialize, value: &dyn Serialize, ) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Map(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_entry(key, value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::Map(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeMap for MakeSerializer<&mut dyn SerializeMap> { type Ok = (); type Error = ErrorImpl; fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_key(&key) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_value(&value) } fn serialize_entry(&mut self, key: &K, value: &V) -> Result<(), Self::Error> where K: ?Sized + serde::Serialize, V: ?Sized + serde::Serialize, { self.0.erased_serialize_entry(&key, &value) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeStruct { fn erased_serialize_field( &mut self, key: &'static str, value: &dyn Serialize, ) -> Result<(), ErrorImpl>; fn erased_skip_field(&mut self, key: &'static str) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeStruct for erase::Serializer where T: serde::Serializer, { fn erased_serialize_field( &mut self, key: &'static str, value: &dyn Serialize, ) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Struct(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_field(key, value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_skip_field(&mut self, key: &'static str) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Struct(serializer) => serializer, _ => unreachable!(), }; serializer.skip_field(key).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::Struct(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeStruct for MakeSerializer<&mut dyn SerializeStruct> { type Ok = (); type Error = ErrorImpl; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_field(key, &value) } fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { self.0.erased_skip_field(key) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } pub trait SerializeStructVariant { fn erased_serialize_field( &mut self, key: &'static str, value: &dyn Serialize, ) -> Result<(), ErrorImpl>; fn erased_skip_field(&mut self, key: &'static str) -> Result<(), ErrorImpl>; fn erased_end(&mut self); } impl SerializeStructVariant for erase::Serializer where T: serde::Serializer, { fn erased_serialize_field( &mut self, key: &'static str, value: &dyn Serialize, ) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::StructVariant(serializer) => serializer, _ => unreachable!(), }; serializer.serialize_field(key, value).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_skip_field(&mut self, key: &'static str) -> Result<(), ErrorImpl> { let serializer = match self { erase::Serializer::Struct(serializer) => serializer, _ => unreachable!(), }; serializer.skip_field(key).map_err(|err| { *self = erase::Serializer::Error(err); ShortCircuit }) } fn erased_end(&mut self) { let serializer = match self.take() { erase::Serializer::StructVariant(serializer) => serializer, _ => unreachable!(), }; *self = match serializer.end() { Ok(ok) => erase::Serializer::Complete(ok), Err(err) => erase::Serializer::Error(err), }; } } impl serde::ser::SerializeStructVariant for MakeSerializer<&mut dyn SerializeStructVariant> { type Ok = (); type Error = ErrorImpl; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: ?Sized + serde::Serialize, { self.0.erased_serialize_field(key, &value) } fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> { self.0.erased_skip_field(key) } fn end(self) -> Result { self.0.erased_end(); Ok(()) } } // IMPL ERASED SERDE FOR ERASED SERDE ////////////////////////////////////////// macro_rules! deref_erased_serializer { (<$T:ident> Serializer for $ty:ty $(where $($where:tt)*)?) => { impl<$T> Serializer for $ty $(where $($where)*)? { fn erased_serialize_bool(&mut self, v: bool) { (**self).erased_serialize_bool(v); } fn erased_serialize_i8(&mut self, v: i8) { (**self).erased_serialize_i8(v); } fn erased_serialize_i16(&mut self, v: i16) { (**self).erased_serialize_i16(v); } fn erased_serialize_i32(&mut self, v: i32) { (**self).erased_serialize_i32(v); } fn erased_serialize_i64(&mut self, v: i64) { (**self).erased_serialize_i64(v); } fn erased_serialize_i128(&mut self, v: i128) { (**self).erased_serialize_i128(v); } fn erased_serialize_u8(&mut self, v: u8) { (**self).erased_serialize_u8(v); } fn erased_serialize_u16(&mut self, v: u16) { (**self).erased_serialize_u16(v); } fn erased_serialize_u32(&mut self, v: u32) { (**self).erased_serialize_u32(v); } fn erased_serialize_u64(&mut self, v: u64) { (**self).erased_serialize_u64(v); } fn erased_serialize_u128(&mut self, v: u128) { (**self).erased_serialize_u128(v); } fn erased_serialize_f32(&mut self, v: f32) { (**self).erased_serialize_f32(v); } fn erased_serialize_f64(&mut self, v: f64) { (**self).erased_serialize_f64(v); } fn erased_serialize_char(&mut self, v: char) { (**self).erased_serialize_char(v); } fn erased_serialize_str(&mut self, v: &str) { (**self).erased_serialize_str(v); } fn erased_serialize_bytes(&mut self, v: &[u8]) { (**self).erased_serialize_bytes(v); } fn erased_serialize_none(&mut self) { (**self).erased_serialize_none(); } fn erased_serialize_some(&mut self, value: &dyn Serialize) { (**self).erased_serialize_some(value); } fn erased_serialize_unit(&mut self) { (**self).erased_serialize_unit(); } fn erased_serialize_unit_struct(&mut self, name: &'static str) { (**self).erased_serialize_unit_struct(name); } fn erased_serialize_unit_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str) { (**self).erased_serialize_unit_variant(name, variant_index, variant); } fn erased_serialize_newtype_struct(&mut self, name: &'static str, value: &dyn Serialize) { (**self).erased_serialize_newtype_struct(name, value); } fn erased_serialize_newtype_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, value: &dyn Serialize) { (**self).erased_serialize_newtype_variant(name, variant_index, variant, value); } fn erased_serialize_seq(&mut self, len: Option) -> Result<&mut dyn SerializeSeq, ErrorImpl> { (**self).erased_serialize_seq(len) } fn erased_serialize_tuple(&mut self, len: usize) -> Result<&mut dyn SerializeTuple, ErrorImpl> { (**self).erased_serialize_tuple(len) } fn erased_serialize_tuple_struct(&mut self, name: &'static str, len: usize) -> Result<&mut dyn SerializeTupleStruct, ErrorImpl> { (**self).erased_serialize_tuple_struct(name, len) } fn erased_serialize_tuple_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<&mut dyn SerializeTupleVariant, ErrorImpl> { (**self).erased_serialize_tuple_variant(name, variant_index, variant, len) } fn erased_serialize_map(&mut self, len: Option) -> Result<&mut dyn SerializeMap, ErrorImpl> { (**self).erased_serialize_map(len) } fn erased_serialize_struct(&mut self, name: &'static str, len: usize) -> Result<&mut dyn SerializeStruct, ErrorImpl> { (**self).erased_serialize_struct(name, len) } fn erased_serialize_struct_variant(&mut self, name: &'static str, variant_index: u32, variant: &'static str, len: usize) -> Result<&mut dyn SerializeStructVariant, ErrorImpl> { (**self).erased_serialize_struct_variant(name, variant_index, variant, len) } fn erased_is_human_readable(&self) -> bool { (**self).erased_is_human_readable() } fn erased_display_error(&self) -> &dyn Display { (**self).erased_display_error() } } impl<$T> sealed::serializer::Sealed for $ty $(where $($where)*)? {} }; } deref_erased_serializer!( Serializer for &mut T where T: ?Sized + Serializer); deref_erased_serializer!( Serializer for Box where T: ?Sized + Serializer); // TEST //////////////////////////////////////////////////////////////////////// #[cfg(test)] mod tests { use super::*; use alloc::{vec, vec::Vec}; use serde_derive::Serialize; fn test_json(t: T) where T: serde::Serialize, { let expected = serde_json::to_vec(&t).unwrap(); // test borrowed trait object { let obj: &dyn Serialize = &t; let mut buf = Vec::new(); { let mut ser = serde_json::Serializer::new(&mut buf); let ser: &mut dyn Serializer = &mut ::erase(&mut ser); obj.erased_serialize(ser).unwrap(); } assert_eq!(buf, expected); } // test boxed trait object { let obj: Box = Box::new(t); let mut buf = Vec::new(); { let mut ser = serde_json::Serializer::new(&mut buf); let mut ser: Box = Box::new(::erase(&mut ser)); obj.erased_serialize(&mut ser).unwrap(); } assert_eq!(buf, expected); } } #[test] fn test_vec() { test_json(vec!["a", "b"]); } #[test] fn test_struct() { #[derive(Serialize)] struct S { f: usize, } test_json(S { f: 256 }); } #[test] fn test_enum() { #[derive(Serialize)] enum E { Unit, Newtype(bool), Tuple(bool, bool), Struct { t: bool, f: bool }, } test_json(E::Unit); test_json(E::Newtype(true)); test_json(E::Tuple(true, false)); test_json(E::Struct { t: true, f: false }); } #[test] fn test_error_custom() { struct Kaboom; impl serde::Serialize for Kaboom { fn serialize(&self, _: S) -> Result where S: serde::Serializer, { use serde::ser::Error as _; Err(S::Error::custom("kaboom")) } } let obj: &dyn Serialize = &Kaboom; let err = serde_json::to_vec(obj).unwrap_err(); assert_eq!(err.to_string(), "kaboom"); } #[test] fn assert_serialize() { fn assert() {} assert::<&dyn Serialize>(); assert::<&(dyn Serialize + Send)>(); assert::<&(dyn Serialize + Sync)>(); assert::<&(dyn Serialize + Send + Sync)>(); assert::<&(dyn Serialize + Sync + Send)>(); assert::>(); assert::>(); assert::>(); assert::>(); assert::>(); assert::>(); assert::>(); assert::>>(); assert::>>(); } }