From 8c1279feaba0058ae10366fd260fe6a8c1faa4c1 Mon Sep 17 00:00:00 2001 From: Trangar Date: Mon, 8 Nov 2021 12:38:29 +0100 Subject: [PATCH] functions to enable encoding/decoding serde types (#422) * functions to enable encoding/decoding serde types * Removed dev feature I forgot to remove * Centralized option variant and len() decoding/encoding --- Cargo.toml | 7 +- src/de/decoder.rs | 6 +- src/de/impls.rs | 24 +- src/de/mod.rs | 24 ++ src/enc/encoder.rs | 4 +- src/enc/impls.rs | 24 +- src/enc/mod.rs | 18 ++ src/error.rs | 42 ++++ src/features/impl_alloc.rs | 32 ++- src/features/impl_std.rs | 3 + src/features/mod.rs | 5 + src/features/serde/de_borrowed.rs | 401 ++++++++++++++++++++++++++++++ src/features/serde/de_owned.rs | 390 +++++++++++++++++++++++++++++ src/features/serde/mod.rs | 28 +++ src/features/serde/ser.rs | 350 ++++++++++++++++++++++++++ src/lib.rs | 4 +- tests/serde.rs | 96 +++++++ 17 files changed, 1420 insertions(+), 38 deletions(-) create mode 100644 src/features/serde/de_borrowed.rs create mode 100644 src/features/serde/de_owned.rs create mode 100644 src/features/serde/mod.rs create mode 100644 src/features/serde/ser.rs diff --git a/Cargo.toml b/Cargo.toml index bbbf0ea..f5c83e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,14 @@ alloc = [] atomic = [] derive = ["bincode_derive"] +# BlockedTODO: https://github.com/rust-lang/cargo/issues/8832 +# We really want these features to automatically be enabled when both "serde" and either "alloc"/"std" is enabled +# But this is currently not possible +serde = ["std", "serde_incl", "serde_incl/std"] + [dependencies] bincode_derive = { path = "derive", version = "2.0.0-alpha.0", optional = true } -serde = { version = "1.0.130", optional = true } +serde_incl = { package = "serde", version = "1.0.130", optional = true } # Used for tests [dev-dependencies] diff --git a/src/de/decoder.rs b/src/de/decoder.rs index df9756a..df2cab4 100644 --- a/src/de/decoder.rs +++ b/src/de/decoder.rs @@ -33,9 +33,9 @@ impl DecoderImpl { } } -impl<'a, R, C: Config> Sealed for &'a mut DecoderImpl {} +impl Sealed for DecoderImpl {} -impl<'a, 'de, R: BorrowReader<'de>, C: Config> BorrowDecoder<'de> for &'a mut DecoderImpl { +impl<'de, R: BorrowReader<'de>, C: Config> BorrowDecoder<'de> for DecoderImpl { type BR = R; fn borrow_reader(&mut self) -> &mut Self::BR { @@ -43,7 +43,7 @@ impl<'a, 'de, R: BorrowReader<'de>, C: Config> BorrowDecoder<'de> for &'a mut De } } -impl<'a, R: Reader, C: Config> Decoder for &'a mut DecoderImpl { +impl Decoder for DecoderImpl { type R = R; type C = C; diff --git a/src/de/impls.rs b/src/de/impls.rs index dc2143e..e7d9656 100644 --- a/src/de/impls.rs +++ b/src/de/impls.rs @@ -378,7 +378,7 @@ impl Decode for char { impl<'a, 'de: 'a> BorrowDecode<'de> for &'a [u8] { fn borrow_decode>(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = super::decode_slice_len(&mut decoder)?; decoder.borrow_reader().take_bytes(len) } } @@ -396,7 +396,7 @@ where { fn decode(mut decoder: D) -> Result { if !D::C::SKIP_FIXED_ARRAY_LENGTH { - let length = usize::decode(&mut decoder)?; + let length = super::decode_slice_len(&mut decoder)?; if length != N { return Err(DecodeError::ArrayLengthMismatch { found: length, @@ -419,12 +419,18 @@ where super::impl_core::collect_into_array(&mut (0..N).map(|_| T::decode(&mut decoder))); // result is only None if N does not match the values of `(0..N)`, which it always should - // So this unsafe should never occur + // So this unwrap should never occur result.unwrap() } } } +impl Decode for () { + fn decode(_: D) -> Result { + Ok(()) + } +} + impl Decode for core::marker::PhantomData { fn decode(_: D) -> Result { Ok(core::marker::PhantomData) @@ -436,18 +442,12 @@ where T: Decode, { fn decode(mut decoder: D) -> Result { - let is_some = u8::decode(&mut decoder)?; - match is_some { - 0 => Ok(None), - 1 => { + match super::decode_option_variant(&mut decoder, core::any::type_name::>())? { + Some(_) => { let val = T::decode(decoder)?; Ok(Some(val)) } - x => Err(DecodeError::UnexpectedVariant { - found: x as u32, - allowed: crate::error::AllowedEnumVariants::Range { max: 1, min: 0 }, - type_name: core::any::type_name::>(), - }), + None => Ok(None), } } } diff --git a/src/de/mod.rs b/src/de/mod.rs index 05d4747..057699e 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -93,3 +93,27 @@ where T::borrow_reader(self) } } + +/// Decodes only the option variant from the decoder. Will not read any more data than that. +#[inline] +pub(crate) fn decode_option_variant( + decoder: D, + type_name: &'static str, +) -> Result, DecodeError> { + let is_some = u8::decode(decoder)?; + match is_some { + 0 => Ok(None), + 1 => Ok(Some(())), + x => Err(DecodeError::UnexpectedVariant { + found: x as u32, + allowed: crate::error::AllowedEnumVariants::Range { max: 1, min: 0 }, + type_name, + }), + } +} + +/// Decodes the length of any slice, container, etc from the decoder +#[inline] +pub(crate) fn decode_slice_len(decoder: D) -> Result { + u64::decode(decoder).map(|v| v as usize) +} diff --git a/src/enc/encoder.rs b/src/enc/encoder.rs index f2c83f9..10d0a2d 100644 --- a/src/enc/encoder.rs +++ b/src/enc/encoder.rs @@ -37,7 +37,7 @@ impl EncoderImpl { } } -impl<'a, W: Writer, C: Config> Encoder for &'a mut EncoderImpl { +impl Encoder for EncoderImpl { type W = W; type C = C; @@ -51,4 +51,4 @@ impl<'a, W: Writer, C: Config> Encoder for &'a mut EncoderImpl { } } -impl<'a, W: Writer, C: Config> Sealed for &'a mut EncoderImpl {} +impl Sealed for EncoderImpl {} diff --git a/src/enc/impls.rs b/src/enc/impls.rs index 6685839..0b80500 100644 --- a/src/enc/impls.rs +++ b/src/enc/impls.rs @@ -8,6 +8,7 @@ use crate::{ }; use core::{ cell::{Cell, RefCell}, + marker::PhantomData, num::{ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, @@ -16,6 +17,18 @@ use core::{ time::Duration, }; +impl Encode for () { + fn encode(&self, _: E) -> Result<(), EncodeError> { + Ok(()) + } +} + +impl Encode for PhantomData { + fn encode(&self, _: E) -> Result<(), EncodeError> { + Ok(()) + } +} + impl Encode for bool { fn encode(&self, encoder: E) -> Result<(), EncodeError> { if *self { 1u8 } else { 0u8 }.encode(encoder) @@ -272,7 +285,7 @@ impl Encode for char { impl Encode for &'_ [u8] { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + super::encode_slice_len(&mut encoder, self.len())?; encoder.writer().write(self) } } @@ -344,7 +357,7 @@ where { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { if !E::C::SKIP_FIXED_ARRAY_LENGTH { - N.encode(&mut encoder)?; + super::encode_slice_len(&mut encoder, N)?; } for item in self.iter() { item.encode(&mut encoder)?; @@ -358,12 +371,11 @@ where T: Encode, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { + super::encode_option_variant(&mut encoder, self)?; if let Some(val) = self { - 1u8.encode(&mut encoder)?; - val.encode(encoder) - } else { - 0u8.encode(encoder) + val.encode(encoder)?; } + Ok(()) } } diff --git a/src/enc/mod.rs b/src/enc/mod.rs index 6f58012..bb11057 100644 --- a/src/enc/mod.rs +++ b/src/enc/mod.rs @@ -50,3 +50,21 @@ where T::config(self) } } + +/// Encode the variant of the given option. Will not encode the option itself. +#[inline] +pub(crate) fn encode_option_variant( + encoder: E, + value: &Option, +) -> Result<(), EncodeError> { + match value { + None => 0u8.encode(encoder), + Some(_) => 1u8.encode(encoder), + } +} + +/// Encodes the length of any slice, container, etc into the given encoder +#[inline] +pub(crate) fn encode_slice_len(encoder: E, len: usize) -> Result<(), EncodeError> { + (len as u64).encode(encoder) +} diff --git a/src/error.rs b/src/error.rs index ec97dff..b9c6a3b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -18,6 +18,10 @@ pub enum EncodeError { /// An uncommon error occured, see the inner text for more information Other(&'static str), + /// An uncommon error occured, see the inner text for more information + #[cfg(feature = "alloc")] + OtherString(alloc::string::String), + /// A `std::path::Path` was being encoded but did not contain a valid `&str` representation #[cfg(feature = "std")] InvalidPathCharacters, @@ -46,6 +50,17 @@ pub enum EncodeError { /// The SystemTime that caused the error time: std::time::SystemTime, }, + + /// Serde provided bincode with a sequence without a length, which is not supported in bincode + #[cfg(feature = "serde")] + SequenceMustHaveLength, +} + +impl core::fmt::Display for EncodeError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // TODO: Improve this? + write!(f, "{:?}", self) + } } /// Errors that can be encounted by decoding a type @@ -104,6 +119,33 @@ pub enum DecodeError { /// The inner exception inner: std::ffi::FromBytesWithNulError, }, + + /// An uncommon error occured, see the inner text for more information + #[cfg(feature = "alloc")] + OtherString(alloc::string::String), + + /// Bincode does not support serde's `any` decoding feature + #[cfg(feature = "serde")] + SerdeAnyNotSupported, + + /// Bincode does not support serde identifiers + #[cfg(feature = "serde")] + SerdeIdentifierNotSupported, + + /// Bincode does not support serde's `ignored_any` + #[cfg(feature = "serde")] + SerdeIgnoredAnyNotSupported, + + /// Serde tried decoding a borrowed value from an owned reader. Use `serde_decode_borrowed_from_*` instead + #[cfg(feature = "serde")] + CannotBorrowOwnedData, +} + +impl core::fmt::Display for DecodeError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // TODO: Improve this? + write!(f, "{:?}", self) + } } impl DecodeError { diff --git a/src/features/impl_alloc.rs b/src/features/impl_alloc.rs index b916310..366aa73 100644 --- a/src/features/impl_alloc.rs +++ b/src/features/impl_alloc.rs @@ -16,10 +16,18 @@ use alloc::{ }; #[derive(Default)] -struct VecWriter { +pub(crate) struct VecWriter { inner: Vec, } +impl VecWriter { + // May not be used in all feature combinations + #[allow(dead_code)] + pub(crate) fn collect(self) -> Vec { + self.inner + } +} + impl enc::write::Writer for VecWriter { fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> { self.inner.extend_from_slice(bytes); @@ -43,7 +51,7 @@ where T: Decode + Ord, { fn decode(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = crate::de::decode_slice_len(&mut decoder)?; let mut map = BinaryHeap::with_capacity(len); for _ in 0..len { let key = T::decode(&mut decoder)?; @@ -58,7 +66,7 @@ where T: Encode + Ord, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for val in self.iter() { val.encode(&mut encoder)?; } @@ -72,7 +80,7 @@ where V: Decode, { fn decode(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = crate::de::decode_slice_len(&mut decoder)?; let mut map = BTreeMap::new(); for _ in 0..len { let key = K::decode(&mut decoder)?; @@ -89,7 +97,7 @@ where V: Encode, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for (key, val) in self.iter() { key.encode(&mut encoder)?; val.encode(&mut encoder)?; @@ -103,7 +111,7 @@ where T: Decode + Ord, { fn decode(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = crate::de::decode_slice_len(&mut decoder)?; let mut map = BTreeSet::new(); for _ in 0..len { let key = T::decode(&mut decoder)?; @@ -118,7 +126,7 @@ where T: Encode + Ord, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for item in self.iter() { item.encode(&mut encoder)?; } @@ -131,7 +139,7 @@ where T: Decode, { fn decode(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = crate::de::decode_slice_len(&mut decoder)?; let mut map = VecDeque::with_capacity(len); for _ in 0..len { let key = T::decode(&mut decoder)?; @@ -146,7 +154,7 @@ where T: Encode, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for item in self.iter() { item.encode(&mut encoder)?; } @@ -159,7 +167,7 @@ where T: Decode, { fn decode(mut decoder: D) -> Result { - let len = usize::decode(&mut decoder)?; + let len = crate::de::decode_slice_len(&mut decoder)?; let mut vec = Vec::with_capacity(len); for _ in 0..len { vec.push(T::decode(&mut decoder)?); @@ -173,7 +181,7 @@ where T: Encode, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for item in self.iter() { item.encode(&mut encoder)?; } @@ -228,7 +236,7 @@ where T: Encode, { fn encode(&self, mut encoder: E) -> Result<(), EncodeError> { - self.len().encode(&mut encoder)?; + crate::enc::encode_slice_len(&mut encoder, self.len())?; for item in self.iter() { item.encode(&mut encoder)?; } diff --git a/src/features/impl_std.rs b/src/features/impl_std.rs index 9d41889..aedb0c9 100644 --- a/src/features/impl_std.rs +++ b/src/features/impl_std.rs @@ -342,3 +342,6 @@ impl Decode for SocketAddrV6 { Ok(Self::new(ip, port, 0, 0)) } } + +impl std::error::Error for EncodeError {} +impl std::error::Error for DecodeError {} diff --git a/src/features/mod.rs b/src/features/mod.rs index ab1b309..c88c63e 100644 --- a/src/features/mod.rs +++ b/src/features/mod.rs @@ -17,3 +17,8 @@ pub use self::impl_std::*; mod derive; #[cfg(feature = "derive")] pub use self::derive::*; + +#[cfg(feature = "serde")] +mod serde; +#[cfg(feature = "serde")] +pub use self::serde::*; diff --git a/src/features/serde/de_borrowed.rs b/src/features/serde/de_borrowed.rs new file mode 100644 index 0000000..71f71b5 --- /dev/null +++ b/src/features/serde/de_borrowed.rs @@ -0,0 +1,401 @@ +use crate::{ + config::Config, + de::{BorrowDecode, BorrowDecoder, Decode}, + error::DecodeError, +}; +use core::marker::PhantomData; +use serde_incl::de::*; + +/// Decode a borrowed type from the given slice. Some parts of the decoded type are expected to be referring to the given slice +pub fn serde_decode_borrowed_from_slice<'de, T, C>( + slice: &'de [u8], + config: C, +) -> Result +where + T: Deserialize<'de>, + C: Config, +{ + let reader = crate::de::read::SliceReader::new(slice); + let mut decoder = crate::de::DecoderImpl::new(reader, config); + let serde_decoder = SerdeDecoder { + de: &mut decoder, + pd: PhantomData, + }; + T::deserialize(serde_decoder) +} + +struct SerdeDecoder<'a, 'de, DE: BorrowDecoder<'de>> { + de: &'a mut DE, + pd: PhantomData<&'de ()>, +} + +impl<'a, 'de, DE: BorrowDecoder<'de>> Deserializer<'de> for SerdeDecoder<'a, 'de, DE> { + type Error = DecodeError; + + fn deserialize_any(self, _: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeAnyNotSupported) + } + + fn deserialize_bool(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_bool(Decode::decode(&mut self.de)?) + } + + fn deserialize_i8(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i8(Decode::decode(&mut self.de)?) + } + + fn deserialize_i16(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i16(Decode::decode(&mut self.de)?) + } + + fn deserialize_i32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i32(Decode::decode(&mut self.de)?) + } + + fn deserialize_i64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i64(Decode::decode(&mut self.de)?) + } + + fn deserialize_u8(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u8(Decode::decode(&mut self.de)?) + } + + fn deserialize_u16(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u16(Decode::decode(&mut self.de)?) + } + + fn deserialize_u32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u32(Decode::decode(&mut self.de)?) + } + + fn deserialize_u64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u64(Decode::decode(&mut self.de)?) + } + + fn deserialize_f32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_f32(Decode::decode(&mut self.de)?) + } + + fn deserialize_f64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_f64(Decode::decode(&mut self.de)?) + } + + fn deserialize_char(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_char(Decode::decode(&mut self.de)?) + } + + fn deserialize_str(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let str = <&'de str>::borrow_decode(&mut self.de)?; + visitor.visit_borrowed_str(str) + } + + fn deserialize_string(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_string(Decode::decode(&mut self.de)?) + } + + fn deserialize_bytes(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let bytes = <&'de [u8]>::borrow_decode(&mut self.de)?; + visitor.visit_borrowed_bytes(bytes) + } + + fn deserialize_byte_buf(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_byte_buf(Decode::decode(&mut self.de)?) + } + + fn deserialize_option(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let variant = crate::de::decode_option_variant(&mut self.de, "Option")?; + if variant.is_some() { + visitor.visit_some(self) + } else { + visitor.visit_none() + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let len = u32::decode(&mut self.de)?; + self.deserialize_tuple(len as usize, visitor) + } + + fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + struct Access<'a, 'b, 'de, DE: BorrowDecoder<'de>> { + deserializer: &'a mut SerdeDecoder<'b, 'de, DE>, + len: usize, + } + + impl<'de, 'a, 'b: 'a, DE: BorrowDecoder<'de> + 'b> SeqAccess<'de> for Access<'a, 'b, 'de, DE> { + type Error = DecodeError; + + fn next_element_seed(&mut self, seed: T) -> Result, DecodeError> + where + T: DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let value = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + pd: PhantomData, + }, + )?; + Ok(Some(value)) + } else { + Ok(None) + } + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + visitor.visit_seq(Access { + deserializer: &mut self, + len, + }) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + struct Access<'a, 'b, 'de, DE: BorrowDecoder<'de>> { + deserializer: &'a mut SerdeDecoder<'b, 'de, DE>, + len: usize, + } + + impl<'de, 'a, 'b: 'a, DE: BorrowDecoder<'de> + 'b> MapAccess<'de> for Access<'a, 'b, 'de, DE> { + type Error = DecodeError; + + fn next_key_seed(&mut self, seed: K) -> Result, DecodeError> + where + K: DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let key = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + pd: PhantomData, + }, + )?; + Ok(Some(key)) + } else { + Ok(None) + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + let value = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + pd: PhantomData, + }, + )?; + Ok(value) + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + let len = usize::decode(&mut self.de)?; + + visitor.visit_map(Access { + deserializer: &mut self, + len, + }) + } + + fn deserialize_struct( + self, + _name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + fn deserialize_identifier(self, _visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeIdentifierNotSupported) + } + + fn deserialize_ignored_any(self, _: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeIgnoredAnyNotSupported) + } +} + +impl<'de, 'a, DE: BorrowDecoder<'de>> EnumAccess<'de> for SerdeDecoder<'a, 'de, DE> { + type Error = DecodeError; + type Variant = Self; + + fn variant_seed(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: DeserializeSeed<'de>, + { + let idx = u32::decode(&mut self.de)?; + let val = seed.deserialize(idx.into_deserializer())?; + Ok((val, self)) + } +} + +impl<'de, 'a, DE: BorrowDecoder<'de>> VariantAccess<'de> for SerdeDecoder<'a, 'de, DE> { + type Error = DecodeError; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + DeserializeSeed::deserialize(seed, self) + } + + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + Deserializer::deserialize_tuple(self, len, visitor) + } + + fn struct_variant( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + Deserializer::deserialize_tuple(self, fields.len(), visitor) + } +} diff --git a/src/features/serde/de_owned.rs b/src/features/serde/de_owned.rs new file mode 100644 index 0000000..a3698e7 --- /dev/null +++ b/src/features/serde/de_owned.rs @@ -0,0 +1,390 @@ +use crate::{ + config::Config, + de::{Decode, Decoder}, + error::DecodeError, +}; +use serde_incl::de::*; + +/// Decode an owned type from the given slice. +/// +/// Note that this does not work with borrowed types like `&str` or `&[u8]`. For that use [serde_decode_borrowed_from_slice]. +pub fn serde_decode_from_slice(slice: &[u8], config: C) -> Result +where + T: DeserializeOwned, + C: Config, +{ + let reader = crate::de::read::SliceReader::new(slice); + let mut decoder = crate::de::DecoderImpl::new(reader, config); + let serde_decoder = SerdeDecoder { de: &mut decoder }; + T::deserialize(serde_decoder) +} + +struct SerdeDecoder<'a, DE: Decoder> { + de: &'a mut DE, +} + +impl<'a, 'de, DE: Decoder> Deserializer<'de> for SerdeDecoder<'a, DE> { + type Error = DecodeError; + + fn deserialize_any(self, _: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeAnyNotSupported) + } + + fn deserialize_bool(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_bool(Decode::decode(&mut self.de)?) + } + + fn deserialize_i8(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i8(Decode::decode(&mut self.de)?) + } + + fn deserialize_i16(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i16(Decode::decode(&mut self.de)?) + } + + fn deserialize_i32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i32(Decode::decode(&mut self.de)?) + } + + fn deserialize_i64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_i64(Decode::decode(&mut self.de)?) + } + + fn deserialize_u8(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u8(Decode::decode(&mut self.de)?) + } + + fn deserialize_u16(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u16(Decode::decode(&mut self.de)?) + } + + fn deserialize_u32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u32(Decode::decode(&mut self.de)?) + } + + fn deserialize_u64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_u64(Decode::decode(&mut self.de)?) + } + + fn deserialize_f32(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_f32(Decode::decode(&mut self.de)?) + } + + fn deserialize_f64(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_f64(Decode::decode(&mut self.de)?) + } + + fn deserialize_char(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_char(Decode::decode(&mut self.de)?) + } + + fn deserialize_str(self, _visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::CannotBorrowOwnedData) + } + + fn deserialize_string(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_string(Decode::decode(&mut self.de)?) + } + + fn deserialize_bytes(self, _visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::CannotBorrowOwnedData) + } + + fn deserialize_byte_buf(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_byte_buf(Decode::decode(&mut self.de)?) + } + + fn deserialize_option(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let variant = crate::de::decode_option_variant(&mut self.de, "Option")?; + if variant.is_some() { + visitor.visit_some(self) + } else { + visitor.visit_none() + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + let len = u32::decode(&mut self.de)?; + self.deserialize_tuple(len as usize, visitor) + } + + fn deserialize_tuple(mut self, len: usize, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + struct Access<'a, 'b, DE: Decoder> { + deserializer: &'a mut SerdeDecoder<'b, DE>, + len: usize, + } + + impl<'de, 'a, 'b: 'a, DE: Decoder + 'b> SeqAccess<'de> for Access<'a, 'b, DE> { + type Error = DecodeError; + + fn next_element_seed(&mut self, seed: T) -> Result, DecodeError> + where + T: DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let value = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + }, + )?; + Ok(Some(value)) + } else { + Ok(None) + } + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + visitor.visit_seq(Access { + deserializer: &mut self, + len, + }) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map(mut self, visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + struct Access<'a, 'b, DE: Decoder> { + deserializer: &'a mut SerdeDecoder<'b, DE>, + len: usize, + } + + impl<'de, 'a, 'b: 'a, DE: Decoder + 'b> MapAccess<'de> for Access<'a, 'b, DE> { + type Error = DecodeError; + + fn next_key_seed(&mut self, seed: K) -> Result, DecodeError> + where + K: DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let key = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + }, + )?; + Ok(Some(key)) + } else { + Ok(None) + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + let value = DeserializeSeed::deserialize( + seed, + SerdeDecoder { + de: self.deserializer.de, + }, + )?; + Ok(value) + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + let len = usize::decode(&mut self.de)?; + + visitor.visit_map(Access { + deserializer: &mut self, + len, + }) + } + + fn deserialize_struct( + self, + _name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + fn deserialize_identifier(self, _visitor: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeIdentifierNotSupported) + } + + fn deserialize_ignored_any(self, _: V) -> Result + where + V: serde_incl::de::Visitor<'de>, + { + Err(DecodeError::SerdeIgnoredAnyNotSupported) + } +} + +impl<'de, 'a, DE: Decoder> EnumAccess<'de> for SerdeDecoder<'a, DE> { + type Error = DecodeError; + type Variant = Self; + + fn variant_seed(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> + where + V: DeserializeSeed<'de>, + { + let idx = u32::decode(&mut self.de)?; + let val = seed.deserialize(idx.into_deserializer())?; + Ok((val, self)) + } +} + +impl<'de, 'a, DE: Decoder> VariantAccess<'de> for SerdeDecoder<'a, DE> { + type Error = DecodeError; + + fn unit_variant(self) -> Result<(), Self::Error> { + Ok(()) + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + DeserializeSeed::deserialize(seed, self) + } + + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + Deserializer::deserialize_tuple(self, len, visitor) + } + + fn struct_variant( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + Deserializer::deserialize_tuple(self, fields.len(), visitor) + } +} diff --git a/src/features/serde/mod.rs b/src/features/serde/mod.rs new file mode 100644 index 0000000..4f88ca2 --- /dev/null +++ b/src/features/serde/mod.rs @@ -0,0 +1,28 @@ +mod de_borrowed; +mod de_owned; +mod ser; + +pub use self::de_borrowed::*; +pub use self::de_owned::*; +pub use self::ser::*; + +impl serde_incl::de::Error for crate::error::DecodeError { + fn custom(msg: T) -> Self + where + T: core::fmt::Display, + { + use alloc::string::ToString; + Self::OtherString(msg.to_string()) + } +} + +impl serde_incl::ser::Error for crate::error::EncodeError { + fn custom(msg: T) -> Self + where + T: core::fmt::Display, + { + use alloc::string::ToString; + + Self::OtherString(msg.to_string()) + } +} diff --git a/src/features/serde/ser.rs b/src/features/serde/ser.rs new file mode 100644 index 0000000..501411d --- /dev/null +++ b/src/features/serde/ser.rs @@ -0,0 +1,350 @@ +use crate::{ + config::Config, + enc::{Encode, Encoder}, + error::EncodeError, +}; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; +use serde_incl::ser::*; + +#[cfg(feature = "alloc")] +/// Encode a `serde` `Serialize` type into a `Vec` with the bincode algorithm +pub fn serde_encode_to_vec(t: T, config: C) -> Result, EncodeError> +where + T: Serialize, + C: Config, +{ + let mut encoder = crate::enc::EncoderImpl::new(crate::VecWriter::default(), config); + let serializer = SerdeEncoder { enc: &mut encoder }; + t.serialize(serializer)?; + Ok(encoder.into_writer().collect()) +} + +/// Encode a `serde` `Serialize` type into a given byte slice with the bincode algorithm +pub fn serde_encode_to_slice(t: T, slice: &mut [u8], config: C) -> Result +where + T: Serialize, + C: Config, +{ + let mut encoder = + crate::enc::EncoderImpl::new(crate::enc::write::SliceWriter::new(slice), config); + let serializer = SerdeEncoder { enc: &mut encoder }; + t.serialize(serializer)?; + Ok(encoder.into_writer().bytes_written()) +} + +struct SerdeEncoder<'a, ENC: Encoder> { + enc: &'a mut ENC, +} + +impl<'a, ENC> Serializer for SerdeEncoder<'a, ENC> +where + ENC: Encoder, +{ + type Ok = (); + + type Error = EncodeError; + + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = Self; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, v: bool) -> Result { + v.encode(self.enc) + } + + fn serialize_i8(self, v: i8) -> Result { + v.encode(self.enc) + } + + fn serialize_i16(self, v: i16) -> Result { + v.encode(self.enc) + } + + fn serialize_i32(self, v: i32) -> Result { + v.encode(self.enc) + } + + fn serialize_i64(self, v: i64) -> Result { + v.encode(self.enc) + } + + fn serialize_u8(self, v: u8) -> Result { + v.encode(self.enc) + } + + fn serialize_u16(self, v: u16) -> Result { + v.encode(self.enc) + } + + fn serialize_u32(self, v: u32) -> Result { + v.encode(self.enc) + } + + fn serialize_u64(self, v: u64) -> Result { + v.encode(self.enc) + } + + fn serialize_f32(self, v: f32) -> Result { + v.encode(self.enc) + } + + fn serialize_f64(self, v: f64) -> Result { + v.encode(self.enc) + } + + fn serialize_char(self, v: char) -> Result { + v.encode(self.enc) + } + + fn serialize_str(self, v: &str) -> Result { + v.encode(self.enc) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + v.encode(self.enc) + } + + fn serialize_none(self) -> Result { + 0u8.encode(self.enc) + } + + fn serialize_some(mut self, value: &T) -> Result + where + T: Serialize, + { + 1u8.encode(&mut self.enc)?; + value.serialize(self) + } + + fn serialize_unit(self) -> Result { + Ok(()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Ok(()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + ) -> Result { + variant_index.encode(self.enc) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + mut self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + variant_index.encode(&mut self.enc)?; + value.serialize(self) + } + + fn serialize_seq(mut self, len: Option) -> Result { + let len = len.ok_or(EncodeError::SequenceMustHaveLength)?; + len.encode(&mut self.enc)?; + Ok(Compound { enc: self.enc }) + } + + fn serialize_tuple(mut self, len: usize) -> Result { + len.encode(&mut self.enc)?; + Ok(self) + } + + fn serialize_tuple_struct( + mut self, + _name: &'static str, + len: usize, + ) -> Result { + len.encode(&mut self.enc)?; + Ok(Compound { enc: self.enc }) + } + + fn serialize_tuple_variant( + mut self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + variant_index.encode(&mut self.enc)?; + Ok(Compound { enc: self.enc }) + } + + fn serialize_map(mut self, len: Option) -> Result { + let len = len.ok_or(EncodeError::SequenceMustHaveLength)?; + len.encode(&mut self.enc)?; + Ok(Compound { enc: self.enc }) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Ok(Compound { enc: self.enc }) + } + + fn serialize_struct_variant( + mut self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + variant_index.encode(&mut self.enc)?; + Ok(Compound { enc: self.enc }) + } +} + +type Compound<'a, ENC> = SerdeEncoder<'a, ENC>; + +impl<'a, ENC: Encoder> SerializeSeq for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeTuple for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeTupleStruct for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeTupleVariant for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeMap for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + key.serialize(SerdeEncoder { enc: self.enc }) + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeStruct for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_field( + &mut self, + _key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} + +impl<'a, ENC: Encoder> SerializeStructVariant for Compound<'a, ENC> { + type Ok = (); + type Error = EncodeError; + + fn serialize_field( + &mut self, + _key: &'static str, + value: &T, + ) -> Result<(), Self::Error> + where + T: Serialize, + { + value.serialize(SerdeEncoder { enc: self.enc }) + } + + fn end(self) -> Result { + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 476df17..576d4c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,10 +120,10 @@ pub fn encode_into_writer( /// [config]: config/index.html pub fn decode_from_slice<'a, D: de::BorrowDecode<'a>, C: Config>( src: &'a [u8], - _config: C, + config: C, ) -> Result { let reader = de::read::SliceReader::new(src); - let mut decoder = de::DecoderImpl::<_, C>::new(reader, _config); + let mut decoder = de::DecoderImpl::<_, C>::new(reader, config); D::borrow_decode(&mut decoder) } diff --git a/tests/serde.rs b/tests/serde.rs index 17705b1..43b0caf 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -1,9 +1,13 @@ #![cfg(all(feature = "serde", feature = "alloc", feature = "derive"))] +extern crate alloc; + +use alloc::string::String; use bincode::config::Configuration; use serde_derive::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, bincode::Encode, bincode::Decode)] +#[serde(crate = "serde_incl")] pub struct SerdeRoundtrip { pub a: u32, #[serde(skip)] @@ -29,3 +33,95 @@ fn test_serde_round_trip() { assert_eq!(result.a, 15); assert_eq!(result.b, 15); } + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(crate = "serde_incl")] +pub struct SerdeWithBorrowedData<'a> { + pub a: u32, + #[serde(skip)] + pub b: u32, + pub str: &'a str, +} + +#[test] +fn test_serialize_deserialize_borrowed_data() { + let input = SerdeWithBorrowedData { + a: 5, + b: 5, + str: "Hello world", + }; + + #[rustfmt::skip] + let expected = &[ + 5, // a + // b is skipped + 11, // str length + b'H', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd' // str + ]; + + let mut result = [0u8; 20]; + let len = + bincode::serde_encode_to_slice(&input, &mut result, Configuration::standard()).unwrap(); + let result = &result[..len]; + assert_eq!(result, expected); + + let result = bincode::serde_encode_to_vec(&input, Configuration::standard()).unwrap(); + + assert_eq!(result, expected); + + let output: SerdeWithBorrowedData = + bincode::serde_decode_borrowed_from_slice(&result, Configuration::standard()).unwrap(); + assert_eq!( + SerdeWithBorrowedData { + b: 0, // remember: b is skipped + ..input + }, + output + ); +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[serde(crate = "serde_incl")] +pub struct SerdeWithOwnedData { + pub a: u32, + #[serde(skip)] + pub b: u32, + pub str: String, +} + +#[test] +fn test_serialize_deserialize_owned_data() { + let input = SerdeWithOwnedData { + a: 5, + b: 5, + str: String::from("Hello world"), + }; + + #[rustfmt::skip] + let expected = &[ + 5, // a + // b is skipped + 11, // str length + b'H', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd' // str + ]; + + let mut result = [0u8; 20]; + let len = + bincode::serde_encode_to_slice(&input, &mut result, Configuration::standard()).unwrap(); + let result = &result[..len]; + assert_eq!(result, expected); + + let result = bincode::serde_encode_to_vec(&input, Configuration::standard()).unwrap(); + + assert_eq!(result, expected); + + let output: SerdeWithOwnedData = + bincode::serde_decode_from_slice(&result, Configuration::standard()).unwrap(); + assert_eq!( + SerdeWithOwnedData { + b: 0, // remember: b is skipped + ..input + }, + output + ); +}