| 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<dyn erased_serde::Serialize>` 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<dyn Serializer>> = Map::new(); |
| /// formats.insert("json", Box::new(<dyn Serializer>::erase(json))); |
| /// formats.insert("cbor", Box::new(<dyn Serializer>::erase(cbor))); |
| /// |
| /// // These are boxed trait objects as well. Same thing here - type erasure |
| /// // makes this possible. |
| /// let mut values: Map<&str, Box<dyn Serialize>> = 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. |
| 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<dyn erased_serde::Serializer>` 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<dyn Serializer>> = Map::new(); |
| /// formats.insert("json", Box::new(<dyn Serializer>::erase(json))); |
| /// formats.insert("cbor", Box::new(<dyn Serializer>::erase(cbor))); |
| /// |
| /// // These are boxed trait objects as well. Same thing here - type erasure |
| /// // makes this possible. |
| /// let mut values: Map<&str, Box<dyn Serialize>> = 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<usize>, |
| ) -> 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<usize>, |
| ) -> 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<dyn Serializer>> = Map::new(); |
| /// formats.insert("json", Box::new(<dyn Serializer>::erase(json))); |
| /// formats.insert("cbor", Box::new(<dyn Serializer>::erase(cbor))); |
| /// |
| /// // These are boxed trait objects as well. Same thing here - type erasure |
| /// // makes this possible. |
| /// let mut values: Map<&str, Box<dyn Serialize>> = 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<S>(serializer: S) -> impl Serializer |
| where |
| S: serde::Serializer, |
| { |
| erase::Serializer::new(serializer) |
| } |
| } |
| |
| // IMPL ERASED SERDE FOR SERDE ///////////////////////////////////////////////// |
| |
| impl<T> 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<T> sealed::serialize::Sealed for T where T: ?Sized + serde::Serialize {} |
| |
| mod erase { |
| use core::mem; |
| |
| pub enum Serializer<S> |
| 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<S> Serializer<S> |
| 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<T> Serializer for erase::Serializer<T> |
| 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<usize>, |
| ) -> 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<usize>, |
| ) -> 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<T> sealed::serializer::Sealed for erase::Serializer<T> where T: serde::Serializer {} |
| |
| pub enum ErrorImpl { |
| ShortCircuit, |
| Custom(Box<String>), |
| } |
| |
| 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<T: Display>(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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
| /// 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<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error> |
| 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>(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::Ok, Self::Error> { |
| self.0.erased_serialize_bool(v); |
| Ok(()) |
| } |
| |
| fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_i8(v); |
| Ok(()) |
| } |
| |
| fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_i16(v); |
| Ok(()) |
| } |
| |
| fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_i32(v); |
| Ok(()) |
| } |
| |
| fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_i64(v); |
| Ok(()) |
| } |
| |
| fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_i128(v); |
| Ok(()) |
| } |
| |
| fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_u8(v); |
| Ok(()) |
| } |
| |
| fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_u16(v); |
| Ok(()) |
| } |
| |
| fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_u32(v); |
| Ok(()) |
| } |
| |
| fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_u64(v); |
| Ok(()) |
| } |
| |
| fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_u128(v); |
| Ok(()) |
| } |
| |
| fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_f32(v); |
| Ok(()) |
| } |
| |
| fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_f64(v); |
| Ok(()) |
| } |
| |
| fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_char(v); |
| Ok(()) |
| } |
| |
| fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_str(v); |
| Ok(()) |
| } |
| |
| fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_bytes(v); |
| Ok(()) |
| } |
| |
| fn serialize_none(self) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_none(); |
| Ok(()) |
| } |
| |
| fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_some(&value); |
| Ok(()) |
| } |
| |
| fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_unit(); |
| Ok(()) |
| } |
| |
| fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> { |
| self.0.erased_serialize_unit_struct(name); |
| Ok(()) |
| } |
| |
| fn serialize_unit_variant( |
| self, |
| name: &'static str, |
| variant_index: u32, |
| variant: &'static str, |
| ) -> Result<Self::Ok, Self::Error> { |
| self.0 |
| .erased_serialize_unit_variant(name, variant_index, variant); |
| Ok(()) |
| } |
| |
| fn serialize_newtype_struct<T>( |
| self, |
| name: &'static str, |
| value: &T, |
| ) -> Result<Self::Ok, Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_newtype_struct(name, &value); |
| Ok(()) |
| } |
| |
| fn serialize_newtype_variant<T>( |
| self, |
| name: &'static str, |
| variant_index: u32, |
| variant: &'static str, |
| value: &T, |
| ) -> Result<Self::Ok, Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0 |
| .erased_serialize_newtype_variant(name, variant_index, variant, &value); |
| Ok(()) |
| } |
| |
| fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> { |
| self.0.erased_serialize_seq(len).map(MakeSerializer) |
| } |
| |
| fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> { |
| self.0.erased_serialize_tuple(len).map(MakeSerializer) |
| } |
| |
| fn serialize_tuple_struct( |
| self, |
| name: &'static str, |
| len: usize, |
| ) -> Result<Self::SerializeTupleStruct, Self::Error> { |
| 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::SerializeTupleVariant, Self::Error> { |
| self.0 |
| .erased_serialize_tuple_variant(name, variant_index, variant, len) |
| .map(MakeSerializer) |
| } |
| |
| fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { |
| self.0.erased_serialize_map(len).map(MakeSerializer) |
| } |
| |
| fn serialize_struct( |
| self, |
| name: &'static str, |
| len: usize, |
| ) -> Result<Self::SerializeStruct, Self::Error> { |
| 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::SerializeStructVariant, Self::Error> { |
| self.0 |
| .erased_serialize_struct_variant(name, variant_index, variant, len) |
| .map(MakeSerializer) |
| } |
| |
| #[cfg(not(feature = "alloc"))] |
| fn collect_str<T>(self, value: &T) -> Result<Self::Ok, Self::Error> |
| 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<T> SerializeSeq for erase::Serializer<T> |
| 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<T>(&mut self, value: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_element(&value) |
| } |
| |
| fn end(self) -> Result<Self::Ok, Self::Error> { |
| 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<T> SerializeTuple for erase::Serializer<T> |
| 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<T>(&mut self, value: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_element(&value) |
| } |
| |
| fn end(self) -> Result<Self::Ok, Self::Error> { |
| 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<T> SerializeTupleStruct for erase::Serializer<T> |
| 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<T>(&mut self, value: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_field(&value) |
| } |
| |
| fn end(self) -> Result<Self::Ok, Self::Error> { |
| 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<T> SerializeTupleVariant for erase::Serializer<T> |
| 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<T>(&mut self, value: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_field(&value) |
| } |
| |
| fn end(self) -> Result<Self::Ok, Self::Error> { |
| 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<T> SerializeMap for erase::Serializer<T> |
| 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<T>(&mut self, key: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_key(&key) |
| } |
| |
| fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error> |
| where |
| T: ?Sized + serde::Serialize, |
| { |
| self.0.erased_serialize_value(&value) |
| } |
| |
| fn serialize_entry<K, V>(&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::Ok, Self::Error> { |
| 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<T> SerializeStruct for erase::Serializer<T> |
| 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<T>(&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::Ok, Self::Error> { |
| 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<T> SerializeStructVariant for erase::Serializer<T> |
| 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<T>(&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::Ok, Self::Error> { |
| 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<usize>) -> 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<usize>) -> 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!(<T> Serializer for &mut T where T: ?Sized + Serializer); |
| deref_erased_serializer!(<T> Serializer for Box<T> 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: 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 <dyn Serializer>::erase(&mut ser); |
| |
| obj.erased_serialize(ser).unwrap(); |
| } |
| |
| assert_eq!(buf, expected); |
| } |
| |
| // test boxed trait object |
| { |
| let obj: Box<dyn Serialize> = Box::new(t); |
| |
| let mut buf = Vec::new(); |
| |
| { |
| let mut ser = serde_json::Serializer::new(&mut buf); |
| let mut ser: Box<dyn Serializer> = Box::new(<dyn Serializer>::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<S>(&self, _: S) -> Result<S::Ok, S::Error> |
| 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<T: serde::Serialize>() {} |
| |
| assert::<&dyn Serialize>(); |
| assert::<&(dyn Serialize + Send)>(); |
| assert::<&(dyn Serialize + Sync)>(); |
| assert::<&(dyn Serialize + Send + Sync)>(); |
| assert::<&(dyn Serialize + Sync + Send)>(); |
| assert::<Vec<&dyn Serialize>>(); |
| assert::<Vec<&(dyn Serialize + Send)>>(); |
| |
| assert::<Box<dyn Serialize>>(); |
| assert::<Box<dyn Serialize + Send>>(); |
| assert::<Box<dyn Serialize + Sync>>(); |
| assert::<Box<dyn Serialize + Send + Sync>>(); |
| assert::<Box<dyn Serialize + Sync + Send>>(); |
| assert::<Vec<Box<dyn Serialize>>>(); |
| assert::<Vec<Box<dyn Serialize + Send>>>(); |
| } |
| } |