From 469d62228ca3bda42fde696c700a99ae752be586 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Mon, 9 Dec 2019 16:57:37 -0800 Subject: [PATCH 01/11] Add new config values --- src/config.rs | 106 ++++++++++++++++++++++++++++++++++++++++-------- src/internal.rs | 22 ++++++++++ 2 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/config.rs b/src/config.rs index 885dbc7f..5f55e9d4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use super::internal::{Bounded, Infinite, SizeLimit}; +use super::internal::{Bounded, Infinite, SizeLimit, SizeType}; use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian}; use de::read::BincodeRead; use error::Result; @@ -9,12 +9,15 @@ use {DeserializerAcceptor, SerializerAcceptor}; use self::EndianOption::*; use self::LimitOption::*; +use internal::U64; struct DefaultOptions(Infinite); pub(crate) trait Options { type Limit: SizeLimit + 'static; type Endian: ByteOrder + 'static; + type StringSize: SizeType + 'static; + type ArraySize: SizeType + 'static; fn limit(&mut self) -> &mut Self::Limit; } @@ -44,6 +47,8 @@ pub(crate) trait OptionsExt: Options + Sized { impl<'a, O: Options> Options for &'a mut O { type Limit = O::Limit; type Endian = O::Endian; + type StringSize = O::StringSize; + type ArraySize = O::ArraySize; #[inline(always)] fn limit(&mut self) -> &mut Self::Limit { @@ -62,6 +67,8 @@ impl DefaultOptions { impl Options for DefaultOptions { type Limit = Infinite; type Endian = LittleEndian; + type StringSize = U64; + type ArraySize = U64; #[inline(always)] fn limit(&mut self) -> &mut Infinite { @@ -82,6 +89,15 @@ enum EndianOption { Native, } +#[derive(Clone, Copy)] +enum LengthOption { + U64, + U32, + U16, + U8, +} + + /// A configuration builder whose options Bincode will use /// while serializing and deserializing. /// @@ -95,10 +111,19 @@ enum EndianOption { /// /// When a byte limit is set, bincode will return `Err` on any deserialization that goes over the limit, or any /// serialization that goes over the limit. +/// ### Array and String sizes +/// When writing a string or an array is serialized the length is written at the beginning so that the data +/// can be deserialized. The option is a way to configure how this length is encoded. The default for both +/// is `U64`. +/// +/// If a string or array is attempted to be serialized that is not fit within the type specified bincode will return `Err` +/// on serialization. #[derive(Clone)] pub struct Config { limit: LimitOption, endian: EndianOption, + string_size: LengthOption, + array_size: LengthOption, } pub(crate) struct WithOtherLimit { @@ -111,6 +136,16 @@ pub(crate) struct WithOtherEndian { _endian: PhantomData, } +pub(crate) struct WithOtherStringLength { + _options: O, + pub(crate) new_string_length: L, +} + +pub(crate) struct WithOtherArrayLength { + _options: O, + pub(crate) new_array_length: L, +} + impl WithOtherLimit { #[inline(always)] pub(crate) fn new(options: O, limit: L) -> WithOtherLimit { @@ -131,9 +166,31 @@ impl WithOtherEndian { } } +impl WithOtherStringLength { + #[inline(always)] + pub(crate) fn new(options: O, limit: L) -> WithOtherStringLength { + WithOtherStringLength { + _options: options, + new_string_length: limit, + } + } +} + +impl WithOtherArrayLength { + #[inline(always)] + pub(crate) fn new(options: O, limit: L) -> WithOtherArrayLength { + WithOtherArrayLength { + _options: options, + new_array_length: limit, + } + } +} + impl Options for WithOtherEndian { type Limit = O::Limit; type Endian = E; + type StringSize = O::StringSize; + type ArraySize = O::ArraySize; #[inline(always)] fn limit(&mut self) -> &mut O::Limit { @@ -144,42 +201,53 @@ impl Options for WithOtherEndian { impl Options for WithOtherLimit { type Limit = L; type Endian = O::Endian; + type StringSize = O::StringSize; + type ArraySize = O::ArraySize; fn limit(&mut self) -> &mut L { &mut self.new_limit } } -macro_rules! config_map { +macro_rules! config_map_limit { ($self:expr, $opts:ident => $call:expr) => { - match ($self.limit, $self.endian) { - (Unlimited, Little) => { - let $opts = DefaultOptions::new().with_no_limit().with_little_endian(); - $call - } - (Unlimited, Big) => { - let $opts = DefaultOptions::new().with_no_limit().with_big_endian(); + match $self.limit { + LimitOption::Unlimited => { + let $opts = $opts.with_no_limit(); $call } - (Unlimited, Native) => { - let $opts = DefaultOptions::new().with_no_limit().with_native_endian(); + LimitOption::Limited(l) => { + let $opts = $opts.with_limit(l); $call } + } + } +} - (Limited(l), Little) => { - let $opts = DefaultOptions::new().with_limit(l).with_little_endian(); +macro_rules! config_map_endian { + ($self:expr, $opts:ident => $call:expr) => { + match $self.endian { + EndianOption::Little => { + let $opts = $opts.with_little_endian(); $call } - (Limited(l), Big) => { - let $opts = DefaultOptions::new().with_limit(l).with_big_endian(); + EndianOption::Big => { + let $opts = $opts.with_big_endian(); $call } - (Limited(l), Native) => { - let $opts = DefaultOptions::new().with_limit(l).with_native_endian(); + EndianOption::Native => { + let $opts = $opts.with_native_endian(); $call } } - }; + } +} + +macro_rules! config_map { + ($self:expr, $opts:ident => $call:expr) => {{ + let $opts = DefaultOptions::new(); + config_map_limit!($self, $opts => config_map_endian!($self, $opts => $call)) + }} } impl Config { @@ -188,6 +256,8 @@ impl Config { Config { limit: LimitOption::Unlimited, endian: EndianOption::Little, + string_size: LengthOption::U64, + array_size: LengthOption::U64, } } diff --git a/src/internal.rs b/src/internal.rs index 968950a3..5d2f9c54 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -189,3 +189,25 @@ impl SizeLimit for Infinite { None } } + +pub(crate) trait SizeType: Clone{} + +/// An 8 byte length +#[derive(Copy, Clone)] +pub struct U64; +impl SizeType for U64{} + +/// A 4 byte length +#[derive(Copy, Clone)] +pub struct U32; +impl SizeType for U32{} + +/// A 2 byte length +#[derive(Copy, Clone)] +pub struct U16; +impl SizeType for U16{} + +/// A 1 byte length +#[derive(Copy, Clone)] +pub struct U8; +impl SizeType for U8{} From bd772698458f5c3e2bb08b8c7e9c452d5526f6b6 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Tue, 10 Dec 2019 15:06:50 -0800 Subject: [PATCH 02/11] Add macros for string length and array length --- src/config.rs | 120 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 106 insertions(+), 14 deletions(-) diff --git a/src/config.rs b/src/config.rs index 5f55e9d4..44a29a18 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use super::internal::{Bounded, Infinite, SizeLimit, SizeType}; +use super::internal::{Bounded, Infinite, SizeLimit, SizeType, U8, U16, U32, U64}; use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian}; use de::read::BincodeRead; use error::Result; @@ -9,7 +9,6 @@ use {DeserializerAcceptor, SerializerAcceptor}; use self::EndianOption::*; use self::LimitOption::*; -use internal::U64; struct DefaultOptions(Infinite); @@ -42,6 +41,14 @@ pub(crate) trait OptionsExt: Options + Sized { fn with_native_endian(self) -> WithOtherEndian { WithOtherEndian::new(self) } + + fn with_string_size(self) -> WithOtherStringLength where S: SizeType { + WithOtherStringLength::new(self) + } + + fn with_array_size(self) -> WithOtherArrayLength where S: SizeType { + WithOtherArrayLength::new(self) + } } impl<'a, O: Options> Options for &'a mut O { @@ -90,7 +97,7 @@ enum EndianOption { } #[derive(Clone, Copy)] -enum LengthOption { +pub enum LengthOption { U64, U32, U16, @@ -137,13 +144,13 @@ pub(crate) struct WithOtherEndian { } pub(crate) struct WithOtherStringLength { - _options: O, - pub(crate) new_string_length: L, + options: O, + _new_string_length: PhantomData, } pub(crate) struct WithOtherArrayLength { - _options: O, - pub(crate) new_array_length: L, + options: O, + _new_array_length: PhantomData, } impl WithOtherLimit { @@ -168,20 +175,20 @@ impl WithOtherEndian { impl WithOtherStringLength { #[inline(always)] - pub(crate) fn new(options: O, limit: L) -> WithOtherStringLength { + pub(crate) fn new(options: O) -> WithOtherStringLength { WithOtherStringLength { - _options: options, - new_string_length: limit, + options: options, + _new_string_length: PhantomData, } } } impl WithOtherArrayLength { #[inline(always)] - pub(crate) fn new(options: O, limit: L) -> WithOtherArrayLength { + pub(crate) fn new(options: O) -> WithOtherArrayLength { WithOtherArrayLength { - _options: options, - new_array_length: limit, + options: options, + _new_array_length: PhantomData, } } } @@ -209,6 +216,28 @@ impl Options for WithOtherLimit { } } +impl Options for WithOtherStringLength { + type Limit = O::Limit; + type Endian = O::Endian; + type StringSize = L; + type ArraySize = O::ArraySize; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +impl Options for WithOtherArrayLength { + type Limit = O::Limit; + type Endian = O::Endian; + type StringSize = O::StringSize; + type ArraySize = L; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + macro_rules! config_map_limit { ($self:expr, $opts:ident => $call:expr) => { match $self.limit { @@ -243,10 +272,59 @@ macro_rules! config_map_endian { } } +macro_rules! config_map_string_length { + ($self:expr, $opts:ident => $call:expr) => { + match $self.string_size { + LengthOption::U64 => { + let $opts = $opts.with_string_size::(); + $call + } + LengthOption::U32 => { + let $opts = $opts.with_string_size::(); + $call + } + LengthOption::U16 => { + let $opts = $opts.with_string_size::(); + $call + } + LengthOption::U8 => { + let $opts = $opts.with_string_size::(); + $call + } + } + } +} + +macro_rules! config_map_array_length { + ($self:expr, $opts:ident => $call:expr) => { + match $self.array_size { + LengthOption::U64 => { + let $opts = $opts.with_array_size::(); + $call + } + LengthOption::U32 => { + let $opts = $opts.with_array_size::(); + $call + } + LengthOption::U16 => { + let $opts = $opts.with_array_size::(); + $call + } + LengthOption::U8 => { + let $opts = $opts.with_array_size::(); + $call + } + } + } +} + macro_rules! config_map { ($self:expr, $opts:ident => $call:expr) => {{ let $opts = DefaultOptions::new(); - config_map_limit!($self, $opts => config_map_endian!($self, $opts => $call)) + config_map_limit!($self, $opts => + config_map_endian!($self, $opts => + config_map_string_length!($self, $opts => + config_map_array_length!($self, $opts => $call)))) }} } @@ -298,6 +376,20 @@ impl Config { self } + /// Sets the size used for lengths of strings + #[inline(always)] + pub fn string_length(&mut self, size: LengthOption) -> &mut Self { + self.string_size = size; + self + } + + /// Sets the size used for lengths of arrays + #[inline(always)] + pub fn array_length(&mut self, size: LengthOption) -> &mut Self { + self.array_size = size; + self + } + /// Serializes a serializable object into a `Vec` of bytes using this configuration #[inline(always)] pub fn serialize(&self, t: &T) -> Result> { From efaf565680481634da0d18608de659eb5f7cee1f Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Wed, 11 Dec 2019 15:27:31 -0800 Subject: [PATCH 03/11] Add tests --- src/config.rs | 5 ++ src/lib.rs | 2 +- tests/test.rs | 147 +++++++++++++++++++++++++++++++++++++------------- 3 files changed, 117 insertions(+), 37 deletions(-) diff --git a/src/config.rs b/src/config.rs index 44a29a18..262f1937 100644 --- a/src/config.rs +++ b/src/config.rs @@ -96,11 +96,16 @@ enum EndianOption { Native, } +/// Used to specify the unit used for length of strings and arrays via `config.string_length` or `config.array_length`. #[derive(Clone, Copy)] pub enum LengthOption { + ///64 unsigned bits U64, + ///32 unsigned bits U32, + ///16 unsigned bits U16, + ///8 unsigned bits U8, } diff --git a/src/lib.rs b/src/lib.rs index ed8e327f..40b91900 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,7 +38,7 @@ mod error; mod internal; mod ser; -pub use config::Config; +pub use config::{Config, LengthOption}; pub use de::read::{BincodeRead, IoReader, SliceReader}; pub use error::{Error, ErrorKind, Result}; diff --git a/tests/test.rs b/tests/test.rs index 33735254..e681e6ca 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -13,37 +13,10 @@ use std::result::Result as StdResult; use bincode::{ config, deserialize, deserialize_from, deserialize_in_place, serialize, serialized_size, - ErrorKind, Result, + ErrorKind, Result, LengthOption, }; use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; -fn the_same(element: V) -where - V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, -{ - let size = serialized_size(&element).unwrap(); - - { - let encoded = serialize(&element).unwrap(); - let decoded = deserialize(&encoded[..]).unwrap(); - - assert_eq!(element, decoded); - assert_eq!(size, encoded.len() as u64); - } - - { - let encoded = config().big_endian().serialize(&element).unwrap(); - let decoded = config().big_endian().deserialize(&encoded[..]).unwrap(); - let decoded_reader = config() - .big_endian() - .deserialize_from(&mut &encoded[..]) - .unwrap(); - - assert_eq!(element, decoded); - assert_eq!(element, decoded_reader); - assert_eq!(size, encoded.len() as u64); - } -} #[test] fn test_numbers() { // unsigned positive @@ -72,6 +45,76 @@ fn test_numbers() { the_same(5f64); } +fn the_same(element: V) + where + V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, +{ + let size = serialized_size(&element).unwrap(); + + { + let encoded = serialize(&element).unwrap(); + let decoded = deserialize(&encoded[..]).unwrap(); + + assert_eq!(element, decoded); + assert_eq!(size, encoded.len() as u64); + } + + { + let encoded = config().big_endian().serialize(&element).unwrap(); + let decoded = config().big_endian().deserialize(&encoded[..]).unwrap(); + let decoded_reader = config() + .big_endian() + .deserialize_from(&mut &encoded[..]) + .unwrap(); + + assert_eq!(element, decoded); + assert_eq!(element, decoded_reader); + assert_eq!(size, encoded.len() as u64); + } +} + +fn the_same_str(element: String) { + let with_length = |length: LengthOption| { + let size = serialized_size(&element).unwrap(); + let encoded = config().string_length(length).serialize(&element).unwrap(); + let decoded: String = config().string_length(length).deserialize(&encoded[..]).unwrap(); + let decoded_reader: String = config() + .string_length(length) + .deserialize_from(&mut &encoded[..]) + .unwrap(); + + assert_eq!(element, decoded); + assert_eq!(element, decoded_reader); + assert_eq!(size, encoded.len() as u64); + }; + with_length(LengthOption::U64); + with_length(LengthOption::U32); + with_length(LengthOption::U16); + with_length(LengthOption::U8); + the_same(element); +} + +fn the_same_vec(element: Vec) where T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static { + let with_length = |length: LengthOption| { + let size = serialized_size(&element).unwrap(); + let encoded = config().string_length(length).serialize(&element).unwrap(); + let decoded: Vec = config().string_length(length).deserialize(&encoded[..]).unwrap(); + let decoded_reader: Vec = config() + .string_length(length) + .deserialize_from(&mut &encoded[..]) + .unwrap(); + + assert_eq!(element, decoded); + assert_eq!(element, decoded_reader); + assert_eq!(size, encoded.len() as u64); + }; + with_length(LengthOption::U64); + with_length(LengthOption::U32); + with_length(LengthOption::U16); + with_length(LengthOption::U8); + the_same(element); +} + #[cfg(has_i128)] #[test] fn test_numbers_128bit() { @@ -88,8 +131,8 @@ fn test_numbers_128bit() { #[test] fn test_string() { - the_same("".to_string()); - the_same("a".to_string()); + the_same_str("".to_string()); + the_same_str("a".to_string()); } #[test] @@ -193,9 +236,9 @@ fn test_enum() { #[test] fn test_vec() { let v: Vec = vec![]; - the_same(v); - the_same(vec![1u64]); - the_same(vec![1u64, 2, 3, 4, 5, 6]); + the_same_vec(v); + the_same_vec(vec![1u64]); + the_same_vec(vec![1u64, 2, 3, 4, 5, 6]); } #[test] @@ -214,8 +257,8 @@ fn test_bool() { #[test] fn test_unicode() { - the_same("å".to_string()); - the_same("aåååååååa".to_string()); + the_same_str("å".to_string()); + the_same_str("aåååååååa".to_string()); } #[test] @@ -417,7 +460,7 @@ fn test_oom_protection() { byte: u8, } let x = config() - .limit(10) + .limit(10) .serialize(&FakeVec { len: 0xffffffffffffffffu64, byte: 1, @@ -716,3 +759,35 @@ fn test_big_endian_deserialize_from_seed() { assert_eq!(seed_data, (0..100).collect::>()); } + +#[test] +fn test_str_size() { + let str = "abcd"; + the_same_str(str.to_owned()); + let size = config().serialized_size(str).unwrap(); + assert_eq!(12, size); + let size = config().string_length(LengthOption::U64).serialized_size(str).unwrap(); + assert_eq!(12, size); + let size = config().string_length(LengthOption::U32).serialized_size(str).unwrap(); + assert_eq!(8, size); + let size = config().string_length(LengthOption::U16).serialized_size(str).unwrap(); + assert_eq!(6, size); + let size = config().string_length(LengthOption::U8).serialized_size(str).unwrap(); + assert_eq!(5, size); +} + +#[test] +fn test_vec_size() { + let v = vec![1u32, 2, 3, 4]; + the_same_vec(v.clone()); + let size = config().serialized_size(&v).unwrap(); + assert_eq!(16 + 8, size); + let size = config().string_length(LengthOption::U64).serialized_size(&v).unwrap(); + assert_eq!(16 + 8, size); + let size = config().string_length(LengthOption::U32).serialized_size(&v).unwrap(); + assert_eq!(16 + 4, size); + let size = config().string_length(LengthOption::U16).serialized_size(&v).unwrap(); + assert_eq!(16 + 2, size); + let size = config().string_length(LengthOption::U8).serialized_size(&v).unwrap(); + assert_eq!(16 + 1, size); +} From d4941ce61d3f740f27ac45bcd657b4ef5d369910 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Wed, 11 Dec 2019 15:35:39 -0800 Subject: [PATCH 04/11] Add test for OOM on string --- tests/test.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test.rs b/tests/test.rs index e681e6ca..f68ae5d0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -469,6 +469,10 @@ fn test_oom_protection() { .limit(10) .deserialize_from(&mut Cursor::new(&x[..])); assert!(y.is_err()); + let y: Result = config() + .limit(10) + .deserialize_from(&mut Cursor::new(&x[..])); + assert!(y.is_err()); } #[test] From a503118f60c22524c82f6432f15b054842f73f28 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Thu, 12 Dec 2019 21:03:35 -0800 Subject: [PATCH 05/11] Add support for variable sized string/vector lengths. --- src/de/mod.rs | 30 ++++++++++++++--------- src/error.rs | 5 ++++ src/internal.rs | 52 ++++++++++++++++++++++++++++++++++++---- src/ser/mod.rs | 37 +++++++++++++++++----------- tests/test.rs | 64 ++++++++++++++++++++++++++++++++----------------- 5 files changed, 136 insertions(+), 52 deletions(-) diff --git a/src/de/mod.rs b/src/de/mod.rs index efe11613..0490def1 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,9 +1,11 @@ use config::Options; use std::io::Read; +use std::convert::TryInto; use self::read::BincodeRead; use byteorder::ReadBytesExt; use internal::SizeLimit; +use internal::SizeType; use serde; use serde::de::Error as DeError; use serde::de::IntoDeserializer; @@ -48,13 +50,17 @@ impl<'de, R: BincodeRead<'de>, O: Options> Deserializer { } fn read_vec(&mut self) -> Result> { - let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); - self.read_bytes(len as u64)?; + let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + self.read_bytes(len)?; + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.get_byte_buffer(len) } fn read_string(&mut self) -> Result { - let vec = self.read_vec()?; + let len = O::StringSize::read(|| serde::Deserialize::deserialize(&mut *self))?; + self.read_bytes(len)?; + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; + let vec = self.reader.get_byte_buffer(len)?; String::from_utf8(vec).map_err(|e| ErrorKind::InvalidUtf8Encoding(e.utf8_error()).into()) } } @@ -196,8 +202,9 @@ where where V: serde::de::Visitor<'de>, { - let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); - try!(self.read_bytes(len as u64)); + let len = O::StringSize::read(|| serde::Deserialize::deserialize(&mut *self))?; + try!(self.read_bytes(len)); + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.forward_read_str(len, visitor) } @@ -212,8 +219,9 @@ where where V: serde::de::Visitor<'de>, { - let len: usize = try!(serde::Deserialize::deserialize(&mut *self)); - try!(self.read_bytes(len as u64)); + let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + try!(self.read_bytes(len)); + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.forward_read_bytes(len, visitor) } @@ -311,8 +319,8 @@ where where V: serde::de::Visitor<'de>, { - let len = try!(serde::Deserialize::deserialize(&mut *self)); - + let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.deserialize_tuple(len, visitor) } @@ -362,8 +370,8 @@ where } } - let len = try!(serde::Deserialize::deserialize(&mut *self)); - + let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; visitor.visit_map(Access { deserializer: self, len: len, diff --git a/src/error.rs b/src/error.rs index 1f52424c..d94914cf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -33,6 +33,8 @@ pub enum ErrorKind { /// If (de)serializing a message takes more than the provided size limit, this /// error is returned. SizeLimit, + /// If serializing a string/vec/array requires more bytes to represent the size than the config allows. + SizeTypeLimit, /// Bincode can not encode sequences of unknown length (like iterators). SequenceMustHaveLength, /// A custom error message from Serde. @@ -54,6 +56,7 @@ impl StdError for ErrorKind { "Bincode doesn't support serde::Deserializer::deserialize_any" } ErrorKind::SizeLimit => "the size limit has been reached", + ErrorKind::SizeTypeLimit => "the size is larger than can be represented with this config", ErrorKind::Custom(ref msg) => msg, } } @@ -68,6 +71,7 @@ impl StdError for ErrorKind { ErrorKind::SequenceMustHaveLength => None, ErrorKind::DeserializeAnyNotSupported => None, ErrorKind::SizeLimit => None, + ErrorKind::SizeTypeLimit => None, ErrorKind::Custom(_) => None, } } @@ -93,6 +97,7 @@ impl fmt::Display for ErrorKind { } ErrorKind::SequenceMustHaveLength => write!(fmt, "{}", self.description()), ErrorKind::SizeLimit => write!(fmt, "{}", self.description()), + ErrorKind::SizeTypeLimit => write!(fmt, "{}", self.description()), ErrorKind::DeserializeAnyNotSupported => write!( fmt, "Bincode does not support the serde::Deserializer::deserialize_any method" diff --git a/src/internal.rs b/src/internal.rs index 5d2f9c54..8642f21e 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -5,6 +5,7 @@ use std::marker::PhantomData; use config::{Options, OptionsExt}; use de::read::BincodeRead; use {ErrorKind, Result}; +use std::convert::{TryInto, TryFrom}; #[derive(Clone)] struct CountSize { @@ -190,24 +191,65 @@ impl SizeLimit for Infinite { } } -pub(crate) trait SizeType: Clone{} +pub(crate) trait SizeType: Clone { + type Primitive : serde::de::DeserializeOwned + TryFrom + Into; + + fn read(mut reader: impl FnMut() -> Result) -> Result { + let result: Self::Primitive = reader()?; + Ok(result.into()) + } + + fn write(writer: S, value: usize) -> Result + where S: serde::Serializer, + Box: From { + let value: Self::Primitive = value.try_into().map_err(|e| ErrorKind::SizeTypeLimit)?; + Self::write_to(writer, value) + } + + fn write_to(writer: S, value: Self::Primitive) -> Result + where S: serde::Serializer, Box: From ; +} /// An 8 byte length #[derive(Copy, Clone)] pub struct U64; -impl SizeType for U64{} +impl SizeType for U64 { + type Primitive = u64; + fn write_to(writer: S, value: Self::Primitive) -> Result + where S: serde::Serializer, Box: From { + writer.serialize_u64(value).map_err(Into::into) + } +} /// A 4 byte length #[derive(Copy, Clone)] pub struct U32; -impl SizeType for U32{} +impl SizeType for U32 { + type Primitive = u32; + fn write_to(writer: S, value: Self::Primitive) -> Result + where S: serde::Serializer, Box: From { + writer.serialize_u32(value).map_err(Into::into) + } +} /// A 2 byte length #[derive(Copy, Clone)] pub struct U16; -impl SizeType for U16{} +impl SizeType for U16 { + type Primitive = u16; + fn write_to(writer: S, value: Self::Primitive) -> Result + where S: serde::Serializer, Box: From { + writer.serialize_u16(value).map_err(Into::into) + } +} /// A 1 byte length #[derive(Copy, Clone)] pub struct U8; -impl SizeType for U8{} +impl SizeType for U8 { + type Primitive = u8; + fn write_to(writer: S, value: Self::Primitive) -> Result + where S: serde::Serializer, Box: From { + writer.serialize_u8(value).map_err(Into::into) + } +} diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 4604c3e6..e0065f92 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -6,8 +6,10 @@ use serde; use byteorder::WriteBytesExt; use super::internal::SizeLimit; +use super::internal::SizeType; use super::{Error, ErrorKind, Result}; use config::Options; +use std::convert::TryInto; /// An Serializer that encodes values directly into a Writer. /// @@ -124,8 +126,10 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { self.writer.write_f64::(v).map_err(Into::into) } + fn serialize_str(self, v: &str) -> Result<()> { - try!(self.serialize_u64(v.len() as u64)); + let ser = &mut *self; + O::StringSize::write(ser, v.len())?; self.writer.write_all(v.as_bytes()).map_err(Into::into) } @@ -136,7 +140,8 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { } fn serialize_bytes(self, v: &[u8]) -> Result<()> { - try!(self.serialize_u64(v.len() as u64)); + let ser = &mut *self; + O::ArraySize::write(ser, v.len())?; self.writer.write_all(v).map_err(Into::into) } @@ -153,8 +158,9 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { } fn serialize_seq(self, len: Option) -> Result { - let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - try!(self.serialize_u64(len as u64)); + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + let ser = &mut *self; + O::ArraySize::write(ser, len)?; Ok(Compound { ser: self }) } @@ -182,8 +188,9 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { } fn serialize_map(self, len: Option) -> Result { - let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - try!(self.serialize_u64(len as u64)); + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + let ser = &mut *self; + O::ArraySize::write(ser, len)?; Ok(Compound { ser: self }) } @@ -330,7 +337,8 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_str(self, v: &str) -> Result<()> { - try!(self.add_value(0 as u64)); + let ser = &mut *self; + O::StringSize::write(ser, v.len())?; self.add_raw(v.len() as u64) } @@ -339,7 +347,8 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_bytes(self, v: &[u8]) -> Result<()> { - try!(self.add_value(0 as u64)); + let ser = &mut *self; + O::ArraySize::write(ser, v.len())?; self.add_raw(v.len() as u64) } @@ -356,9 +365,9 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_seq(self, len: Option) -> Result { - let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - - try!(self.serialize_u64(len as u64)); + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + let ser = &mut *self; + O::ArraySize::write(ser, len)?; Ok(SizeCompound { ser: self }) } @@ -386,9 +395,9 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_map(self, len: Option) -> Result { - let len = try!(len.ok_or(ErrorKind::SequenceMustHaveLength)); - - try!(self.serialize_u64(len as u64)); + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + let ser = &mut *self; + O::ArraySize::write(ser, len)?; Ok(SizeCompound { ser: self }) } diff --git a/tests/test.rs b/tests/test.rs index f68ae5d0..c9969319 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -75,7 +75,7 @@ fn the_same(element: V) fn the_same_str(element: String) { let with_length = |length: LengthOption| { - let size = serialized_size(&element).unwrap(); + let size = config().string_length(length).serialized_size(&element).unwrap(); let encoded = config().string_length(length).serialize(&element).unwrap(); let decoded: String = config().string_length(length).deserialize(&encoded[..]).unwrap(); let decoded_reader: String = config() @@ -96,7 +96,7 @@ fn the_same_str(element: String) { fn the_same_vec(element: Vec) where T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static { let with_length = |length: LengthOption| { - let size = serialized_size(&element).unwrap(); + let size = config().string_length(length).serialized_size(&element).unwrap(); let encoded = config().string_length(length).serialize(&element).unwrap(); let decoded: Vec = config().string_length(length).deserialize(&encoded[..]).unwrap(); let decoded_reader: Vec = config() @@ -768,30 +768,50 @@ fn test_big_endian_deserialize_from_seed() { fn test_str_size() { let str = "abcd"; the_same_str(str.to_owned()); - let size = config().serialized_size(str).unwrap(); - assert_eq!(12, size); - let size = config().string_length(LengthOption::U64).serialized_size(str).unwrap(); - assert_eq!(12, size); - let size = config().string_length(LengthOption::U32).serialized_size(str).unwrap(); - assert_eq!(8, size); - let size = config().string_length(LengthOption::U16).serialized_size(str).unwrap(); - assert_eq!(6, size); - let size = config().string_length(LengthOption::U8).serialized_size(str).unwrap(); - assert_eq!(5, size); + let expected = config().serialized_size(str).unwrap(); + let actual = config().serialize(str).unwrap().len(); + assert_eq!(12, expected); + assert_eq!(12, actual); + let expected = config().string_length(LengthOption::U64).serialized_size(str).unwrap(); + let actual = config().string_length(LengthOption::U64).serialize(str).unwrap().len(); + assert_eq!(12, expected); + assert_eq!(12, actual); + let expected = config().string_length(LengthOption::U32).serialized_size(str).unwrap(); + let actual = config().string_length(LengthOption::U32).serialize(str).unwrap().len(); + assert_eq!(8, expected); + assert_eq!(8, actual); + let expected = config().string_length(LengthOption::U16).serialized_size(str).unwrap(); + let actual = config().string_length(LengthOption::U16).serialize(str).unwrap().len(); + assert_eq!(6, expected); + assert_eq!(6, actual); + let expected = config().string_length(LengthOption::U8).serialized_size(str).unwrap(); + let actual = config().string_length(LengthOption::U8).serialize(str).unwrap().len(); + assert_eq!(5, expected); + assert_eq!(5, actual); } #[test] fn test_vec_size() { let v = vec![1u32, 2, 3, 4]; the_same_vec(v.clone()); - let size = config().serialized_size(&v).unwrap(); - assert_eq!(16 + 8, size); - let size = config().string_length(LengthOption::U64).serialized_size(&v).unwrap(); - assert_eq!(16 + 8, size); - let size = config().string_length(LengthOption::U32).serialized_size(&v).unwrap(); - assert_eq!(16 + 4, size); - let size = config().string_length(LengthOption::U16).serialized_size(&v).unwrap(); - assert_eq!(16 + 2, size); - let size = config().string_length(LengthOption::U8).serialized_size(&v).unwrap(); - assert_eq!(16 + 1, size); + let expected = config().serialized_size(&v).unwrap(); + let actual = config().serialize(&v).unwrap().len(); + assert_eq!(16 + 8, expected); + assert_eq!(16 + 8, actual); + let expected = config().array_length(LengthOption::U64).serialized_size(&v).unwrap(); + let actual = config().array_length(LengthOption::U64).serialize(&v).unwrap().len(); + assert_eq!(16 + 8, expected); + assert_eq!(16 + 8, actual); + let expected = config().array_length(LengthOption::U32).serialized_size(&v).unwrap(); + let actual = config().array_length(LengthOption::U32).serialize(&v).unwrap().len(); + assert_eq!(16 + 4, expected); + assert_eq!(16 + 4, actual); + let expected = config().array_length(LengthOption::U16).serialized_size(&v).unwrap(); + let actual = config().array_length(LengthOption::U16).serialize(&v).unwrap().len(); + assert_eq!(16 + 2, expected); + assert_eq!(16 + 2, actual); + let expected = config().array_length(LengthOption::U8).serialized_size(&v).unwrap(); + let actual = config().array_length(LengthOption::U8).serialize(&v).unwrap().len(); + assert_eq!(16 + 1, expected); + assert_eq!(16 + 1, actual); } From 6acce498553645d60cfdf7f02e19237ed5807cb1 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Thu, 12 Dec 2019 21:09:29 -0800 Subject: [PATCH 06/11] cargo format --- src/config.rs | 21 +++++--- src/de/mod.rs | 12 ++--- src/de/read.rs | 4 +- src/error.rs | 4 +- src/internal.rs | 34 ++++++++---- src/ser/mod.rs | 1 - tests/test.rs | 137 ++++++++++++++++++++++++++++++++++++------------ 7 files changed, 151 insertions(+), 62 deletions(-) diff --git a/src/config.rs b/src/config.rs index 262f1937..ea10a270 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use super::internal::{Bounded, Infinite, SizeLimit, SizeType, U8, U16, U32, U64}; +use super::internal::{Bounded, Infinite, SizeLimit, SizeType, U16, U32, U64, U8}; use byteorder::{BigEndian, ByteOrder, LittleEndian, NativeEndian}; use de::read::BincodeRead; use error::Result; @@ -42,11 +42,17 @@ pub(crate) trait OptionsExt: Options + Sized { WithOtherEndian::new(self) } - fn with_string_size(self) -> WithOtherStringLength where S: SizeType { + fn with_string_size(self) -> WithOtherStringLength + where + S: SizeType, + { WithOtherStringLength::new(self) } - fn with_array_size(self) -> WithOtherArrayLength where S: SizeType { + fn with_array_size(self) -> WithOtherArrayLength + where + S: SizeType, + { WithOtherArrayLength::new(self) } } @@ -109,7 +115,6 @@ pub enum LengthOption { U8, } - /// A configuration builder whose options Bincode will use /// while serializing and deserializing. /// @@ -255,7 +260,7 @@ macro_rules! config_map_limit { $call } } - } + }; } macro_rules! config_map_endian { @@ -274,7 +279,7 @@ macro_rules! config_map_endian { $call } } - } + }; } macro_rules! config_map_string_length { @@ -297,7 +302,7 @@ macro_rules! config_map_string_length { $call } } - } + }; } macro_rules! config_map_array_length { @@ -320,7 +325,7 @@ macro_rules! config_map_array_length { $call } } - } + }; } macro_rules! config_map { diff --git a/src/de/mod.rs b/src/de/mod.rs index 0490def1..309bf614 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,6 +1,6 @@ use config::Options; -use std::io::Read; use std::convert::TryInto; +use std::io::Read; use self::read::BincodeRead; use byteorder::ReadBytesExt; @@ -189,12 +189,10 @@ where return Err(error()); } - let res = try!( - str::from_utf8(&buf[..width]) - .ok() - .and_then(|s| s.chars().next()) - .ok_or(error()) - ); + let res = try!(str::from_utf8(&buf[..width]) + .ok() + .and_then(|s| s.chars().next()) + .ok_or(error())); visitor.visit_char(res) } diff --git a/src/de/read.rs b/src/de/read.rs index ffc5ae2a..92f900c1 100644 --- a/src/de/read.rs +++ b/src/de/read.rs @@ -145,9 +145,7 @@ where // Then create a slice with the length as our desired length. This is // safe as long as we only write (no reads) to this buffer, because // `reserve_exact` above has allocated this space. - let buf = unsafe { - slice::from_raw_parts_mut(self.temp_buffer.as_mut_ptr(), length) - }; + let buf = unsafe { slice::from_raw_parts_mut(self.temp_buffer.as_mut_ptr(), length) }; // This method is assumed to properly handle slices which include // uninitialized bytes (as ours does). See discussion at the link below. diff --git a/src/error.rs b/src/error.rs index d94914cf..ae06cb84 100644 --- a/src/error.rs +++ b/src/error.rs @@ -56,7 +56,9 @@ impl StdError for ErrorKind { "Bincode doesn't support serde::Deserializer::deserialize_any" } ErrorKind::SizeLimit => "the size limit has been reached", - ErrorKind::SizeTypeLimit => "the size is larger than can be represented with this config", + ErrorKind::SizeTypeLimit => { + "the size is larger than can be represented with this config" + } ErrorKind::Custom(ref msg) => msg, } } diff --git a/src/internal.rs b/src/internal.rs index 8642f21e..0929fd60 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -4,8 +4,8 @@ use std::marker::PhantomData; use config::{Options, OptionsExt}; use de::read::BincodeRead; +use std::convert::{TryFrom, TryInto}; use {ErrorKind, Result}; -use std::convert::{TryInto, TryFrom}; #[derive(Clone)] struct CountSize { @@ -192,7 +192,7 @@ impl SizeLimit for Infinite { } pub(crate) trait SizeType: Clone { - type Primitive : serde::de::DeserializeOwned + TryFrom + Into; + type Primitive: serde::de::DeserializeOwned + TryFrom + Into; fn read(mut reader: impl FnMut() -> Result) -> Result { let result: Self::Primitive = reader()?; @@ -200,14 +200,18 @@ pub(crate) trait SizeType: Clone { } fn write(writer: S, value: usize) -> Result - where S: serde::Serializer, - Box: From { + where + S: serde::Serializer, + Box: From, + { let value: Self::Primitive = value.try_into().map_err(|e| ErrorKind::SizeTypeLimit)?; Self::write_to(writer, value) } fn write_to(writer: S, value: Self::Primitive) -> Result - where S: serde::Serializer, Box: From ; + where + S: serde::Serializer, + Box: From; } /// An 8 byte length @@ -216,7 +220,10 @@ pub struct U64; impl SizeType for U64 { type Primitive = u64; fn write_to(writer: S, value: Self::Primitive) -> Result - where S: serde::Serializer, Box: From { + where + S: serde::Serializer, + Box: From, + { writer.serialize_u64(value).map_err(Into::into) } } @@ -227,7 +234,10 @@ pub struct U32; impl SizeType for U32 { type Primitive = u32; fn write_to(writer: S, value: Self::Primitive) -> Result - where S: serde::Serializer, Box: From { + where + S: serde::Serializer, + Box: From, + { writer.serialize_u32(value).map_err(Into::into) } } @@ -238,7 +248,10 @@ pub struct U16; impl SizeType for U16 { type Primitive = u16; fn write_to(writer: S, value: Self::Primitive) -> Result - where S: serde::Serializer, Box: From { + where + S: serde::Serializer, + Box: From, + { writer.serialize_u16(value).map_err(Into::into) } } @@ -249,7 +262,10 @@ pub struct U8; impl SizeType for U8 { type Primitive = u8; fn write_to(writer: S, value: Self::Primitive) -> Result - where S: serde::Serializer, Box: From { + where + S: serde::Serializer, + Box: From, + { writer.serialize_u8(value).map_err(Into::into) } } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index e0065f92..b288d280 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -126,7 +126,6 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { self.writer.write_f64::(v).map_err(Into::into) } - fn serialize_str(self, v: &str) -> Result<()> { let ser = &mut *self; O::StringSize::write(ser, v.len())?; diff --git a/tests/test.rs b/tests/test.rs index c9969319..89c899b6 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -13,7 +13,7 @@ use std::result::Result as StdResult; use bincode::{ config, deserialize, deserialize_from, deserialize_in_place, serialize, serialized_size, - ErrorKind, Result, LengthOption, + ErrorKind, LengthOption, Result, }; use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; @@ -46,8 +46,8 @@ fn test_numbers() { } fn the_same(element: V) - where - V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, +where + V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, { let size = serialized_size(&element).unwrap(); @@ -75,9 +75,15 @@ fn the_same(element: V) fn the_same_str(element: String) { let with_length = |length: LengthOption| { - let size = config().string_length(length).serialized_size(&element).unwrap(); + let size = config() + .string_length(length) + .serialized_size(&element) + .unwrap(); let encoded = config().string_length(length).serialize(&element).unwrap(); - let decoded: String = config().string_length(length).deserialize(&encoded[..]).unwrap(); + let decoded: String = config() + .string_length(length) + .deserialize(&encoded[..]) + .unwrap(); let decoded_reader: String = config() .string_length(length) .deserialize_from(&mut &encoded[..]) @@ -94,11 +100,20 @@ fn the_same_str(element: String) { the_same(element); } -fn the_same_vec(element: Vec) where T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static { +fn the_same_vec(element: Vec) +where + T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, +{ let with_length = |length: LengthOption| { - let size = config().string_length(length).serialized_size(&element).unwrap(); + let size = config() + .string_length(length) + .serialized_size(&element) + .unwrap(); let encoded = config().string_length(length).serialize(&element).unwrap(); - let decoded: Vec = config().string_length(length).deserialize(&encoded[..]).unwrap(); + let decoded: Vec = config() + .string_length(length) + .deserialize(&encoded[..]) + .unwrap(); let decoded_reader: Vec = config() .string_length(length) .deserialize_from(&mut &encoded[..]) @@ -375,12 +390,10 @@ fn test_serialized_size_bounded() { assert!(config().limit(7).serialized_size(&0u64).is_err()); assert!(config().limit(7).serialized_size(&"").is_err()); assert!(config().limit(8 + 0).serialized_size(&"a").is_err()); - assert!( - config() - .limit(8 + 3 * 4 - 1) - .serialized_size(&vec![0u32, 1u32, 2u32]) - .is_err() - ); + assert!(config() + .limit(8 + 3 * 4 - 1) + .serialized_size(&vec![0u32, 1u32, 2u32]) + .is_err()); } #[test] @@ -460,11 +473,12 @@ fn test_oom_protection() { byte: u8, } let x = config() - .limit(10) + .limit(10) .serialize(&FakeVec { len: 0xffffffffffffffffu64, byte: 1, - }).unwrap(); + }) + .unwrap(); let y: Result> = config() .limit(10) .deserialize_from(&mut Cursor::new(&x[..])); @@ -626,7 +640,8 @@ fn test_zero_copy_parse_deserialize_into() { slice: &encoded[..], }, &mut target, - ).unwrap(); + ) + .unwrap(); assert_eq!(target, f); } } @@ -772,20 +787,48 @@ fn test_str_size() { let actual = config().serialize(str).unwrap().len(); assert_eq!(12, expected); assert_eq!(12, actual); - let expected = config().string_length(LengthOption::U64).serialized_size(str).unwrap(); - let actual = config().string_length(LengthOption::U64).serialize(str).unwrap().len(); + let expected = config() + .string_length(LengthOption::U64) + .serialized_size(str) + .unwrap(); + let actual = config() + .string_length(LengthOption::U64) + .serialize(str) + .unwrap() + .len(); assert_eq!(12, expected); assert_eq!(12, actual); - let expected = config().string_length(LengthOption::U32).serialized_size(str).unwrap(); - let actual = config().string_length(LengthOption::U32).serialize(str).unwrap().len(); + let expected = config() + .string_length(LengthOption::U32) + .serialized_size(str) + .unwrap(); + let actual = config() + .string_length(LengthOption::U32) + .serialize(str) + .unwrap() + .len(); assert_eq!(8, expected); assert_eq!(8, actual); - let expected = config().string_length(LengthOption::U16).serialized_size(str).unwrap(); - let actual = config().string_length(LengthOption::U16).serialize(str).unwrap().len(); + let expected = config() + .string_length(LengthOption::U16) + .serialized_size(str) + .unwrap(); + let actual = config() + .string_length(LengthOption::U16) + .serialize(str) + .unwrap() + .len(); assert_eq!(6, expected); assert_eq!(6, actual); - let expected = config().string_length(LengthOption::U8).serialized_size(str).unwrap(); - let actual = config().string_length(LengthOption::U8).serialize(str).unwrap().len(); + let expected = config() + .string_length(LengthOption::U8) + .serialized_size(str) + .unwrap(); + let actual = config() + .string_length(LengthOption::U8) + .serialize(str) + .unwrap() + .len(); assert_eq!(5, expected); assert_eq!(5, actual); } @@ -798,20 +841,48 @@ fn test_vec_size() { let actual = config().serialize(&v).unwrap().len(); assert_eq!(16 + 8, expected); assert_eq!(16 + 8, actual); - let expected = config().array_length(LengthOption::U64).serialized_size(&v).unwrap(); - let actual = config().array_length(LengthOption::U64).serialize(&v).unwrap().len(); + let expected = config() + .array_length(LengthOption::U64) + .serialized_size(&v) + .unwrap(); + let actual = config() + .array_length(LengthOption::U64) + .serialize(&v) + .unwrap() + .len(); assert_eq!(16 + 8, expected); assert_eq!(16 + 8, actual); - let expected = config().array_length(LengthOption::U32).serialized_size(&v).unwrap(); - let actual = config().array_length(LengthOption::U32).serialize(&v).unwrap().len(); + let expected = config() + .array_length(LengthOption::U32) + .serialized_size(&v) + .unwrap(); + let actual = config() + .array_length(LengthOption::U32) + .serialize(&v) + .unwrap() + .len(); assert_eq!(16 + 4, expected); assert_eq!(16 + 4, actual); - let expected = config().array_length(LengthOption::U16).serialized_size(&v).unwrap(); - let actual = config().array_length(LengthOption::U16).serialize(&v).unwrap().len(); + let expected = config() + .array_length(LengthOption::U16) + .serialized_size(&v) + .unwrap(); + let actual = config() + .array_length(LengthOption::U16) + .serialize(&v) + .unwrap() + .len(); assert_eq!(16 + 2, expected); assert_eq!(16 + 2, actual); - let expected = config().array_length(LengthOption::U8).serialized_size(&v).unwrap(); - let actual = config().array_length(LengthOption::U8).serialize(&v).unwrap().len(); + let expected = config() + .array_length(LengthOption::U8) + .serialized_size(&v) + .unwrap(); + let actual = config() + .array_length(LengthOption::U8) + .serialize(&v) + .unwrap() + .len(); assert_eq!(16 + 1, expected); assert_eq!(16 + 1, actual); } From 2c8e013785e909238eb6bb72cb48ce6f26676f48 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Thu, 12 Dec 2019 21:14:11 -0800 Subject: [PATCH 07/11] Fix all warnings --- src/config.rs | 3 --- src/error.rs | 2 +- src/internal.rs | 2 +- src/ser/mod.rs | 6 +----- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/config.rs b/src/config.rs index ea10a270..18b0e492 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,9 +7,6 @@ use std::io::{Read, Write}; use std::marker::PhantomData; use {DeserializerAcceptor, SerializerAcceptor}; -use self::EndianOption::*; -use self::LimitOption::*; - struct DefaultOptions(Infinite); pub(crate) trait Options { diff --git a/src/error.rs b/src/error.rs index ae06cb84..09a760c4 100644 --- a/src/error.rs +++ b/src/error.rs @@ -63,7 +63,7 @@ impl StdError for ErrorKind { } } - fn cause(&self) -> Option<&error::Error> { + fn cause(&self) -> Option<&dyn error::Error> { match *self { ErrorKind::Io(ref err) => Some(err), ErrorKind::InvalidUtf8Encoding(_) => None, diff --git a/src/internal.rs b/src/internal.rs index 0929fd60..3206abde 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -204,7 +204,7 @@ pub(crate) trait SizeType: Clone { S: serde::Serializer, Box: From, { - let value: Self::Primitive = value.try_into().map_err(|e| ErrorKind::SizeTypeLimit)?; + let value: Self::Primitive = value.try_into().map_err(|_e| ErrorKind::SizeTypeLimit)?; Self::write_to(writer, value) } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index b288d280..8e1b93c6 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -9,7 +9,6 @@ use super::internal::SizeLimit; use super::internal::SizeType; use super::{Error, ErrorKind, Result}; use config::Options; -use std::convert::TryInto; /// An Serializer that encodes values directly into a Writer. /// @@ -248,10 +247,7 @@ pub(crate) struct SizeChecker { } impl SizeChecker { - pub fn new(options: O) -> SizeChecker { - SizeChecker { options: options } - } - + fn add_raw(&mut self, size: u64) -> Result<()> { self.options.limit().add(size) } From 5265c4da0e1a3b0061411943d8359971bc930325 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Fri, 13 Dec 2019 11:31:01 -0800 Subject: [PATCH 08/11] Fix backwards compatability with Rust 1.18 --- src/de/mod.rs | 12 ++++++------ src/error.rs | 2 +- src/internal.rs | 2 +- src/ser/mod.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/de/mod.rs b/src/de/mod.rs index 309bf614..79bcc20e 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -50,14 +50,14 @@ impl<'de, R: BincodeRead<'de>, O: Options> Deserializer { } fn read_vec(&mut self) -> Result> { - let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::ArraySize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; self.read_bytes(len)?; let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.get_byte_buffer(len) } fn read_string(&mut self) -> Result { - let len = O::StringSize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::StringSize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; self.read_bytes(len)?; let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; let vec = self.reader.get_byte_buffer(len)?; @@ -200,7 +200,7 @@ where where V: serde::de::Visitor<'de>, { - let len = O::StringSize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::StringSize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; try!(self.read_bytes(len)); let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.forward_read_str(len, visitor) @@ -217,7 +217,7 @@ where where V: serde::de::Visitor<'de>, { - let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::ArraySize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; try!(self.read_bytes(len)); let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.reader.forward_read_bytes(len, visitor) @@ -317,7 +317,7 @@ where where V: serde::de::Visitor<'de>, { - let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::ArraySize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; self.deserialize_tuple(len, visitor) } @@ -368,7 +368,7 @@ where } } - let len = O::ArraySize::read(|| serde::Deserialize::deserialize(&mut *self))?; + let len = O::ArraySize::read(&mut || serde::Deserialize::deserialize(&mut *self))?; let len: usize = len.try_into().map_err(|_e| ErrorKind::SizeLimit)?; visitor.visit_map(Access { deserializer: self, diff --git a/src/error.rs b/src/error.rs index 09a760c4..ae06cb84 100644 --- a/src/error.rs +++ b/src/error.rs @@ -63,7 +63,7 @@ impl StdError for ErrorKind { } } - fn cause(&self) -> Option<&dyn error::Error> { + fn cause(&self) -> Option<&error::Error> { match *self { ErrorKind::Io(ref err) => Some(err), ErrorKind::InvalidUtf8Encoding(_) => None, diff --git a/src/internal.rs b/src/internal.rs index 3206abde..1a1939e6 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -194,7 +194,7 @@ impl SizeLimit for Infinite { pub(crate) trait SizeType: Clone { type Primitive: serde::de::DeserializeOwned + TryFrom + Into; - fn read(mut reader: impl FnMut() -> Result) -> Result { + fn read(reader: &mut FnMut() -> Result) -> Result { let result: Self::Primitive = reader()?; Ok(result.into()) } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 8e1b93c6..bec03b1d 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -247,7 +247,7 @@ pub(crate) struct SizeChecker { } impl SizeChecker { - + fn add_raw(&mut self, size: u64) -> Result<()> { self.options.limit().add(size) } From 5bfe729694e8e3faf83f774000433a0685fe8afe Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Fri, 13 Dec 2019 15:44:05 -0800 Subject: [PATCH 09/11] Copy try_from/try_into from std to allow building on older versions of the compiler. --- src/de/mod.rs | 2 +- src/internal.rs | 2 +- src/lib.rs | 1 + src/try_into.rs | 225 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 src/try_into.rs diff --git a/src/de/mod.rs b/src/de/mod.rs index 79bcc20e..b5cbf7ac 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,6 +1,6 @@ use config::Options; -use std::convert::TryInto; use std::io::Read; +use super::try_into::*; use self::read::BincodeRead; use byteorder::ReadBytesExt; diff --git a/src/internal.rs b/src/internal.rs index 1a1939e6..0bdb9aa4 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -4,8 +4,8 @@ use std::marker::PhantomData; use config::{Options, OptionsExt}; use de::read::BincodeRead; -use std::convert::{TryFrom, TryInto}; use {ErrorKind, Result}; +use try_into::*; #[derive(Clone)] struct CountSize { diff --git a/src/lib.rs b/src/lib.rs index 40b91900..0c4d60e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ mod de; mod error; mod internal; mod ser; +mod try_into; pub use config::{Config, LengthOption}; pub use de::read::{BincodeRead, IoReader, SliceReader}; diff --git a/src/try_into.rs b/src/try_into.rs new file mode 100644 index 00000000..137034fe --- /dev/null +++ b/src/try_into.rs @@ -0,0 +1,225 @@ +///For whatever reason bincode is stuck in Rust 1.18, so this module replicates some of the +///functionality of try_from / try_into from the standard library. THERE IS NO ORIGINAL CODE HERE +pub(crate) trait TryFrom: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_from(value: T) -> Result; +} + +pub(crate) trait TryInto: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_into(self) -> Result; +} + +// TryFrom implies TryInto +impl TryInto for T where U: TryFrom +{ + type Error = U::Error; + + fn try_into(self) -> Result { + U::try_from(self) + } +} + +pub(crate) struct TryFromIntError(()); + +// no possible bounds violation +macro_rules! try_from_unbounded { + ($source:ty, $($target:ty),*) => {$( + impl TryFrom<$source> for $target { + type Error = TryFromIntError; + + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. + #[inline] + fn try_from(value: $source) -> Result { + Ok(value as $target) + } + } + )*} +} + +// only negative bounds +macro_rules! try_from_lower_bounded { + ($source:ty, $($target:ty),*) => {$( + impl TryFrom<$source> for $target { + type Error = TryFromIntError; + + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. + #[inline] + fn try_from(u: $source) -> Result<$target, TryFromIntError> { + if u >= 0 { + Ok(u as $target) + } else { + Err(TryFromIntError(())) + } + } + } + )*} +} + +// unsigned to signed (only positive bound) +macro_rules! try_from_upper_bounded { + ($source:ty, $($target:ty),*) => {$( + impl TryFrom<$source> for $target { + type Error = TryFromIntError; + + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. + #[inline] + fn try_from(u: $source) -> Result<$target, TryFromIntError> { + if u > (<$target>::max_value() as $source) { + Err(TryFromIntError(())) + } else { + Ok(u as $target) + } + } + } + )*} +} + +// all other cases +macro_rules! try_from_both_bounded { + ($source:ty, $($target:ty),*) => {$( + impl TryFrom<$source> for $target { + type Error = TryFromIntError; + + /// Try to create the target number type from a source + /// number type. This returns an error if the source value + /// is outside of the range of the target type. + #[inline] + fn try_from(u: $source) -> Result<$target, TryFromIntError> { + let min = <$target>::min_value() as $source; + let max = <$target>::max_value() as $source; + if u < min || u > max { + Err(TryFromIntError(())) + } else { + Ok(u as $target) + } + } + } + )*} +} + +macro_rules! rev { + ($mac:ident, $source:ty, $($target:ty),*) => {$( + $mac!($target, $source); + )*} +} + +// intra-sign conversions +try_from_upper_bounded!(u16, u8); +try_from_upper_bounded!(u32, u16, u8); +try_from_upper_bounded!(u64, u32, u16, u8); +try_from_upper_bounded!(u128, u64, u32, u16, u8); + +try_from_both_bounded!(i16, i8); +try_from_both_bounded!(i32, i16, i8); +try_from_both_bounded!(i64, i32, i16, i8); +try_from_both_bounded!(i128, i64, i32, i16, i8); + +// unsigned-to-signed +try_from_upper_bounded!(u8, i8); +try_from_upper_bounded!(u16, i8, i16); +try_from_upper_bounded!(u32, i8, i16, i32); +try_from_upper_bounded!(u64, i8, i16, i32, i64); +try_from_upper_bounded!(u128, i8, i16, i32, i64, i128); + +// signed-to-unsigned +try_from_lower_bounded!(i8, u8, u16, u32, u64, u128); +try_from_lower_bounded!(i16, u16, u32, u64, u128); +try_from_lower_bounded!(i32, u32, u64, u128); +try_from_lower_bounded!(i64, u64, u128); +try_from_lower_bounded!(i128, u128); +try_from_both_bounded!(i16, u8); +try_from_both_bounded!(i32, u16, u8); +try_from_both_bounded!(i64, u32, u16, u8); +try_from_both_bounded!(i128, u64, u32, u16, u8); + +// usize/isize +try_from_upper_bounded!(usize, isize); +try_from_lower_bounded!(isize, usize); + +#[cfg(target_pointer_width = "16")] +mod ptr_try_from_impls { + use super::TryFromIntError; + use super::TryFrom; + + try_from_upper_bounded!(usize, u8); + try_from_unbounded!(usize, u16, u32, u64, u128); + try_from_upper_bounded!(usize, i8, i16); + try_from_unbounded!(usize, i32, i64, i128); + + try_from_both_bounded!(isize, u8); + try_from_lower_bounded!(isize, u16, u32, u64, u128); + try_from_both_bounded!(isize, i8); + try_from_unbounded!(isize, i16, i32, i64, i128); + + rev!(try_from_upper_bounded, usize, u32, u64, u128); + rev!(try_from_lower_bounded, usize, i8, i16); + rev!(try_from_both_bounded, usize, i32, i64, i128); + + rev!(try_from_upper_bounded, isize, u16, u32, u64, u128); + rev!(try_from_both_bounded, isize, i32, i64, i128); +} + +#[cfg(target_pointer_width = "32")] +mod ptr_try_from_impls { + use super::TryFromIntError; + use super::TryFrom; + + try_from_upper_bounded!(usize, u8, u16); + try_from_unbounded!(usize, u32, u64, u128); + try_from_upper_bounded!(usize, i8, i16, i32); + try_from_unbounded!(usize, i64, i128); + + try_from_both_bounded!(isize, u8, u16); + try_from_lower_bounded!(isize, u32, u64, u128); + try_from_both_bounded!(isize, i8, i16); + try_from_unbounded!(isize, i32, i64, i128); + + rev!(try_from_unbounded, usize, u32); + rev!(try_from_upper_bounded, usize, u64, u128); + rev!(try_from_lower_bounded, usize, i8, i16, i32); + rev!(try_from_both_bounded, usize, i64, i128); + + rev!(try_from_unbounded, isize, u16); + rev!(try_from_upper_bounded, isize, u32, u64, u128); + rev!(try_from_unbounded, isize, i32); + rev!(try_from_both_bounded, isize, i64, i128); +} + +#[cfg(target_pointer_width = "64")] +mod ptr_try_from_impls { + use super::TryFromIntError; + use super::TryFrom; + + try_from_upper_bounded!(usize, u8, u16, u32); + try_from_unbounded!(usize, u64, u128); + try_from_upper_bounded!(usize, i8, i16, i32, i64); + try_from_unbounded!(usize, i128); + + try_from_both_bounded!(isize, u8, u16, u32); + try_from_lower_bounded!(isize, u64, u128); + try_from_both_bounded!(isize, i8, i16, i32); + try_from_unbounded!(isize, i64, i128); + + rev!(try_from_unbounded, usize, u32, u64); + rev!(try_from_upper_bounded, usize, u128); + rev!(try_from_lower_bounded, usize, i8, i16, i32, i64); + rev!(try_from_both_bounded, usize, i128); + + rev!(try_from_unbounded, isize, u16, u32); + rev!(try_from_upper_bounded, isize, u64, u128); + rev!(try_from_unbounded, isize, i32, i64); + rev!(try_from_both_bounded, isize, i128); +} From 3bc1a3c18fb805b1e4c58fb9f852a7af5c6750cd Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Sat, 14 Dec 2019 13:27:40 -0800 Subject: [PATCH 10/11] Remove 128 bit conversions --- src/try_into.rs | 57 +++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/try_into.rs b/src/try_into.rs index 137034fe..52b3f6c5 100644 --- a/src/try_into.rs +++ b/src/try_into.rs @@ -120,30 +120,25 @@ macro_rules! rev { try_from_upper_bounded!(u16, u8); try_from_upper_bounded!(u32, u16, u8); try_from_upper_bounded!(u64, u32, u16, u8); -try_from_upper_bounded!(u128, u64, u32, u16, u8); try_from_both_bounded!(i16, i8); try_from_both_bounded!(i32, i16, i8); try_from_both_bounded!(i64, i32, i16, i8); -try_from_both_bounded!(i128, i64, i32, i16, i8); // unsigned-to-signed try_from_upper_bounded!(u8, i8); try_from_upper_bounded!(u16, i8, i16); try_from_upper_bounded!(u32, i8, i16, i32); try_from_upper_bounded!(u64, i8, i16, i32, i64); -try_from_upper_bounded!(u128, i8, i16, i32, i64, i128); // signed-to-unsigned -try_from_lower_bounded!(i8, u8, u16, u32, u64, u128); -try_from_lower_bounded!(i16, u16, u32, u64, u128); -try_from_lower_bounded!(i32, u32, u64, u128); -try_from_lower_bounded!(i64, u64, u128); -try_from_lower_bounded!(i128, u128); +try_from_lower_bounded!(i8, u8, u16, u32, u64); +try_from_lower_bounded!(i16, u16, u32, u64); +try_from_lower_bounded!(i32, u32, u64); +try_from_lower_bounded!(i64, u64); try_from_both_bounded!(i16, u8); try_from_both_bounded!(i32, u16, u8); try_from_both_bounded!(i64, u32, u16, u8); -try_from_both_bounded!(i128, u64, u32, u16, u8); // usize/isize try_from_upper_bounded!(usize, isize); @@ -155,21 +150,21 @@ mod ptr_try_from_impls { use super::TryFrom; try_from_upper_bounded!(usize, u8); - try_from_unbounded!(usize, u16, u32, u64, u128); + try_from_unbounded!(usize, u16, u32, u64); try_from_upper_bounded!(usize, i8, i16); - try_from_unbounded!(usize, i32, i64, i128); + try_from_unbounded!(usize, i32, i64); try_from_both_bounded!(isize, u8); - try_from_lower_bounded!(isize, u16, u32, u64, u128); + try_from_lower_bounded!(isize, u16, u32, u64); try_from_both_bounded!(isize, i8); - try_from_unbounded!(isize, i16, i32, i64, i128); + try_from_unbounded!(isize, i16, i32, i64); - rev!(try_from_upper_bounded, usize, u32, u64, u128); + rev!(try_from_upper_bounded, usize, u32, u64); rev!(try_from_lower_bounded, usize, i8, i16); - rev!(try_from_both_bounded, usize, i32, i64, i128); + rev!(try_from_both_bounded, usize, i32, i64); - rev!(try_from_upper_bounded, isize, u16, u32, u64, u128); - rev!(try_from_both_bounded, isize, i32, i64, i128); + rev!(try_from_upper_bounded, isize, u16, u32, u64); + rev!(try_from_both_bounded, isize, i32, i64); } #[cfg(target_pointer_width = "32")] @@ -178,24 +173,24 @@ mod ptr_try_from_impls { use super::TryFrom; try_from_upper_bounded!(usize, u8, u16); - try_from_unbounded!(usize, u32, u64, u128); + try_from_unbounded!(usize, u32, u64); try_from_upper_bounded!(usize, i8, i16, i32); - try_from_unbounded!(usize, i64, i128); + try_from_unbounded!(usize, i64); try_from_both_bounded!(isize, u8, u16); - try_from_lower_bounded!(isize, u32, u64, u128); + try_from_lower_bounded!(isize, u32, u64); try_from_both_bounded!(isize, i8, i16); - try_from_unbounded!(isize, i32, i64, i128); + try_from_unbounded!(isize, i32, i64); rev!(try_from_unbounded, usize, u32); - rev!(try_from_upper_bounded, usize, u64, u128); + rev!(try_from_upper_bounded, usize, u64); rev!(try_from_lower_bounded, usize, i8, i16, i32); - rev!(try_from_both_bounded, usize, i64, i128); + rev!(try_from_both_bounded, usize, i64); rev!(try_from_unbounded, isize, u16); - rev!(try_from_upper_bounded, isize, u32, u64, u128); + rev!(try_from_upper_bounded, isize, u32, u64); rev!(try_from_unbounded, isize, i32); - rev!(try_from_both_bounded, isize, i64, i128); + rev!(try_from_both_bounded, isize, i64); } #[cfg(target_pointer_width = "64")] @@ -204,22 +199,18 @@ mod ptr_try_from_impls { use super::TryFrom; try_from_upper_bounded!(usize, u8, u16, u32); - try_from_unbounded!(usize, u64, u128); + try_from_unbounded!(usize, u64); try_from_upper_bounded!(usize, i8, i16, i32, i64); - try_from_unbounded!(usize, i128); try_from_both_bounded!(isize, u8, u16, u32); - try_from_lower_bounded!(isize, u64, u128); + try_from_lower_bounded!(isize, u64); try_from_both_bounded!(isize, i8, i16, i32); - try_from_unbounded!(isize, i64, i128); + try_from_unbounded!(isize, i64); rev!(try_from_unbounded, usize, u32, u64); - rev!(try_from_upper_bounded, usize, u128); rev!(try_from_lower_bounded, usize, i8, i16, i32, i64); - rev!(try_from_both_bounded, usize, i128); rev!(try_from_unbounded, isize, u16, u32); - rev!(try_from_upper_bounded, isize, u64, u128); + rev!(try_from_upper_bounded, isize, u64); rev!(try_from_unbounded, isize, i32, i64); - rev!(try_from_both_bounded, isize, i128); } From cf6595d463417817b769f62b65a618e22a95b726 Mon Sep 17 00:00:00 2001 From: Tom Kaitchuck Date: Tue, 17 Dec 2019 20:27:13 -0800 Subject: [PATCH 11/11] Inline local variables --- src/ser/mod.rs | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ser/mod.rs b/src/ser/mod.rs index bec03b1d..ada219d5 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -126,8 +126,7 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { } fn serialize_str(self, v: &str) -> Result<()> { - let ser = &mut *self; - O::StringSize::write(ser, v.len())?; + O::StringSize::write(&mut *self, v.len())?; self.writer.write_all(v.as_bytes()).map_err(Into::into) } @@ -138,8 +137,7 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { } fn serialize_bytes(self, v: &[u8]) -> Result<()> { - let ser = &mut *self; - O::ArraySize::write(ser, v.len())?; + O::ArraySize::write(&mut *self, v.len())?; self.writer.write_all(v).map_err(Into::into) } @@ -157,8 +155,7 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { fn serialize_seq(self, len: Option) -> Result { let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; - let ser = &mut *self; - O::ArraySize::write(ser, len)?; + O::ArraySize::write(&mut *self, len)?; Ok(Compound { ser: self }) } @@ -187,8 +184,7 @@ impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { fn serialize_map(self, len: Option) -> Result { let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; - let ser = &mut *self; - O::ArraySize::write(ser, len)?; + O::ArraySize::write(&mut *self, len)?; Ok(Compound { ser: self }) } @@ -332,8 +328,7 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_str(self, v: &str) -> Result<()> { - let ser = &mut *self; - O::StringSize::write(ser, v.len())?; + O::StringSize::write(&mut *self, v.len())?; self.add_raw(v.len() as u64) } @@ -342,8 +337,7 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { } fn serialize_bytes(self, v: &[u8]) -> Result<()> { - let ser = &mut *self; - O::ArraySize::write(ser, v.len())?; + O::ArraySize::write(&mut *self, v.len())?; self.add_raw(v.len() as u64) } @@ -361,8 +355,7 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { fn serialize_seq(self, len: Option) -> Result { let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; - let ser = &mut *self; - O::ArraySize::write(ser, len)?; + O::ArraySize::write(&mut *self, len)?; Ok(SizeCompound { ser: self }) } @@ -391,8 +384,7 @@ impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { fn serialize_map(self, len: Option) -> Result { let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; - let ser = &mut *self; - O::ArraySize::write(ser, len)?; + O::ArraySize::write(&mut *self, len)?; Ok(SizeCompound { ser: self }) }