From 9835e2ae736235810b4ea1c162ca5e65c547e770 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 04:49:50 +0200 Subject: Merging upstream version 1.71.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/bincode/.cargo-checksum.json | 1 + vendor/bincode/Cargo.toml | 37 ++ vendor/bincode/LICENSE.md | 21 + vendor/bincode/readme.md | 112 +++++ vendor/bincode/src/byteorder.rs | 385 +++++++++++++++ vendor/bincode/src/config/endian.rs | 27 + vendor/bincode/src/config/int.rs | 682 ++++++++++++++++++++++++++ vendor/bincode/src/config/legacy.rs | 253 ++++++++++ vendor/bincode/src/config/limit.rs | 49 ++ vendor/bincode/src/config/mod.rs | 408 +++++++++++++++ vendor/bincode/src/config/trailing.rs | 37 ++ vendor/bincode/src/de/mod.rs | 515 +++++++++++++++++++ vendor/bincode/src/de/read.rs | 202 ++++++++ vendor/bincode/src/error.rs | 115 +++++ vendor/bincode/src/internal.rs | 124 +++++ vendor/bincode/src/lib.rs | 201 ++++++++ vendor/bincode/src/ser/mod.rs | 772 +++++++++++++++++++++++++++++ vendor/bincode/tests/test.rs | 899 ++++++++++++++++++++++++++++++++++ 18 files changed, 4840 insertions(+) create mode 100644 vendor/bincode/.cargo-checksum.json create mode 100644 vendor/bincode/Cargo.toml create mode 100644 vendor/bincode/LICENSE.md create mode 100644 vendor/bincode/readme.md create mode 100644 vendor/bincode/src/byteorder.rs create mode 100644 vendor/bincode/src/config/endian.rs create mode 100644 vendor/bincode/src/config/int.rs create mode 100644 vendor/bincode/src/config/legacy.rs create mode 100644 vendor/bincode/src/config/limit.rs create mode 100644 vendor/bincode/src/config/mod.rs create mode 100644 vendor/bincode/src/config/trailing.rs create mode 100644 vendor/bincode/src/de/mod.rs create mode 100644 vendor/bincode/src/de/read.rs create mode 100644 vendor/bincode/src/error.rs create mode 100644 vendor/bincode/src/internal.rs create mode 100644 vendor/bincode/src/lib.rs create mode 100644 vendor/bincode/src/ser/mod.rs create mode 100644 vendor/bincode/tests/test.rs (limited to 'vendor/bincode') diff --git a/vendor/bincode/.cargo-checksum.json b/vendor/bincode/.cargo-checksum.json new file mode 100644 index 000000000..87171ef36 --- /dev/null +++ b/vendor/bincode/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"bec3b1248d39cbaa31f04baba57650b70540ce6458d81e0f83c7bd178d7636f2","LICENSE.md":"237710d4c9dd8eb7fead2c9c433be493a878f547d1093812feff43d18abe5896","readme.md":"46bed3c85db9aafba5999d5632753d93dda40e3af3b8b3e2bbab12a75f42f05e","src/byteorder.rs":"2c9de3d574339be9cafd47333e57dc92bd9014b2e0fd1a400683d06ceceb6fa7","src/config/endian.rs":"4cc21f604425f3bd7b169019a2560356dad62c8e0199c8cb46bb5e209ae70432","src/config/int.rs":"66065835fc56a515df57f2c19df6bfc8295a87266d05cf6dac17f0380cae2af6","src/config/legacy.rs":"db8dca430bb718058289b99528cd8e62502fdaf93d652ca6772026de8a784e40","src/config/limit.rs":"e5883d901a4b216e622f092503767ace121c396b645a24e28dcc528eab54d8e3","src/config/mod.rs":"d79766ac15a213293e8d684ba639e0968bf883214007ffcab6c9f7128a12bdb6","src/config/trailing.rs":"dec18dbbd847e87456bcaa93413c377d922efb4239f0600879c7440540a07a3e","src/de/mod.rs":"b91fe450aedbc9332f59f189dd438fdabfb4d7482f951aa40db18b49fa91b942","src/de/read.rs":"bb32d12d8dee1b0df426e3cc48288664152468c48b1df2448edd18bf1df921be","src/error.rs":"f1154e228fd0d2dfc73bed9efb410875a8b84a77b40c2dfbe37d3dd244ed0741","src/internal.rs":"ac343424a43899f4f9d44855484bc84cd86a07fafc9ae721d92a2095afeb8b05","src/lib.rs":"c68480ac64127e196b49b75a676b7c3a3bd723020b168b4f6093a64feb548b2e","src/ser/mod.rs":"a9cbf0b6c24c73d6f51994ebdb4c3b8ecd410011b083b7a882d823a7271d2221","tests/test.rs":"63974ad679ec47fe0497f6a21caf17f5b8040b68ef70df7af508bfa8c0e01d59"},"package":"b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"} \ No newline at end of file diff --git a/vendor/bincode/Cargo.toml b/vendor/bincode/Cargo.toml new file mode 100644 index 000000000..4c81bfc5a --- /dev/null +++ b/vendor/bincode/Cargo.toml @@ -0,0 +1,37 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "bincode" +version = "1.3.3" +authors = ["Ty Overby ", "Francesco Mazzoli ", "David Tolnay ", "Zoey Riordan "] +exclude = ["logo.png", "examples/*", ".gitignore", ".travis.yml"] +publish = true +description = "A binary serialization / deserialization strategy that uses Serde for transforming structs into bytes and vice versa!" +documentation = "https://docs.rs/bincode" +readme = "./readme.md" +keywords = ["binary", "encode", "decode", "serialize", "deserialize"] +categories = ["encoding", "network-programming"] +license = "MIT" +repository = "https://github.com/servo/bincode" +[dependencies.serde] +version = "1.0.63" +[dev-dependencies.serde_bytes] +version = "0.11" + +[dev-dependencies.serde_derive] +version = "1.0.27" + +[features] +i128 = [] +[badges.travis-ci] +repository = "servo/bincode" diff --git a/vendor/bincode/LICENSE.md b/vendor/bincode/LICENSE.md new file mode 100644 index 000000000..3db1f0117 --- /dev/null +++ b/vendor/bincode/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Ty Overby + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/bincode/readme.md b/vendor/bincode/readme.md new file mode 100644 index 000000000..e91651220 --- /dev/null +++ b/vendor/bincode/readme.md @@ -0,0 +1,112 @@ +# Bincode + + + +![CI](https://github.com/servo/bincode/workflows/CI/badge.svg) +[![](https://meritbadge.herokuapp.com/bincode)](https://crates.io/crates/bincode) +[![](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) +[![](https://img.shields.io/badge/bincode-rustc_1.18+-lightgray.svg)](https://blog.rust-lang.org/2017/06/08/Rust-1.18.html) + +A compact encoder / decoder pair that uses a binary zero-fluff encoding scheme. +The size of the encoded object will be the same or smaller than the size that +the object takes up in memory in a running Rust program. + +In addition to exposing two simple functions +(one that encodes to `Vec`, and one that decodes from `&[u8]`), +binary-encode exposes a Reader/Writer API that makes it work +perfectly with other stream-based APIs such as Rust files, network streams, +and the [flate2-rs](https://github.com/alexcrichton/flate2-rs) compression +library. + +## [API Documentation](https://docs.rs/bincode/) + +## Bincode in the wild + +* [google/tarpc](https://github.com/google/tarpc): Bincode is used to serialize and deserialize networked RPC messages. +* [servo/webrender](https://github.com/servo/webrender): Bincode records webrender API calls for record/replay-style graphics debugging. +* [servo/ipc-channel](https://github.com/servo/ipc-channel): IPC-Channel uses Bincode to send structs between processes using a channel-like API. + +## Example + +```rust +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +struct Entity { + x: f32, + y: f32, +} + +#[derive(Serialize, Deserialize, PartialEq, Debug)] +struct World(Vec); + +fn main() { + let world = World(vec![Entity { x: 0.0, y: 4.0 }, Entity { x: 10.0, y: 20.5 }]); + + let encoded: Vec = bincode::serialize(&world).unwrap(); + + // 8 bytes for the length of the vector, 4 bytes per float. + assert_eq!(encoded.len(), 8 + 4 * 4); + + let decoded: World = bincode::deserialize(&encoded[..]).unwrap(); + + assert_eq!(world, decoded); +} +``` + +## Details + +The encoding (and thus decoding) proceeds unsurprisingly -- primitive +types are encoded according to the underlying `Writer`, tuples and +structs are encoded by encoding their fields one-by-one, and enums are +encoded by first writing out the tag representing the variant and +then the contents. + +However, there are some implementation details to be aware of: + +* `isize`/`usize` are encoded as `i64`/`u64`, for portability. +* enums variants are encoded as a `u32` instead of a `usize`. + `u32` is enough for all practical uses. +* `str` is encoded as `(u64, &[u8])`, where the `u64` is the number of + bytes contained in the encoded string. + +## Specification + +Bincode's format will eventually be codified into a specification, along with +its configuration options and default configuration. In the meantime, here are +some frequently asked questions regarding use of the crate: + +### Is Bincode suitable for storage? + +The encoding format is stable across minor revisions, provided the same +configuration is used. This should ensure that later versions can still read +data produced by a previous versions of the library if no major version change +has occured. + +Bincode is invariant over byte-order in the default configuration +(`bincode::options::DefaultOptions`), making an exchange between different +architectures possible. It is also rather space efficient, as it stores no +metadata like struct field names in the output format and writes long streams of +binary data without needing any potentially size-increasing encoding. + +As a result, Bincode is suitable for storing data. Be aware that it does not +implement any sort of data versioning scheme or file headers, as these +features are outside the scope of this crate. + +### Is Bincode suitable for untrusted inputs? + +Bincode attempts to protect against hostile data. There is a maximum size +configuration available (`bincode::config::Bounded`), but not enabled in the +default configuration. Enabling it causes pre-allocation size to be limited to +prevent against memory exhaustion attacks. + +Deserializing any incoming data will not cause undefined behavior or memory +issues, assuming that the deserialization code for the struct is safe itself. + +Bincode can be used for untrusted inputs in the sense that it will not create a +security issues in your application, provided the configuration is changed to enable a +maximum size limit. Malicious inputs will fail upon deserialization. + +### What is Bincode's MSRV (minimum supported Rust version)? + +Bincode 1.0 maintains support for rust 1.18.0. Any changes to this are considered a breaking change for semver purposes. \ No newline at end of file diff --git a/vendor/bincode/src/byteorder.rs b/vendor/bincode/src/byteorder.rs new file mode 100644 index 000000000..298503d20 --- /dev/null +++ b/vendor/bincode/src/byteorder.rs @@ -0,0 +1,385 @@ +// Copyright (c) 2015 Andrew Gallant + +use std::io; +use std::io::Result; +use std::ptr::copy_nonoverlapping; + +#[derive(Copy, Clone)] +pub struct LittleEndian; + +#[derive(Copy, Clone)] +pub struct BigEndian; + +#[cfg(target_endian = "little")] +pub type NativeEndian = LittleEndian; + +#[cfg(target_endian = "big")] +pub type NativeEndian = BigEndian; + +macro_rules! read_num_bytes { + ($ty:ty, $size:expr, $src:expr, $which:ident) => {{ + assert!($size == ::std::mem::size_of::<$ty>()); + assert!($size <= $src.len()); + let mut data: $ty = 0; + unsafe { + copy_nonoverlapping($src.as_ptr(), &mut data as *mut $ty as *mut u8, $size); + } + data.$which() + }}; +} + +macro_rules! write_num_bytes { + ($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => {{ + assert!($size <= $dst.len()); + unsafe { + // N.B. https://github.com/rust-lang/rust/issues/22776 + let bytes = *(&$n.$which() as *const _ as *const [u8; $size]); + copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size); + } + }}; +} + +impl ByteOrder for LittleEndian { + #[inline] + fn read_u16(buf: &[u8]) -> u16 { + read_num_bytes!(u16, 2, buf, to_le) + } + + #[inline] + fn read_u32(buf: &[u8]) -> u32 { + read_num_bytes!(u32, 4, buf, to_le) + } + + #[inline] + fn read_u64(buf: &[u8]) -> u64 { + read_num_bytes!(u64, 8, buf, to_le) + } + + #[inline] + fn write_u16(buf: &mut [u8], n: u16) { + write_num_bytes!(u16, 2, n, buf, to_le); + } + + #[inline] + fn write_u32(buf: &mut [u8], n: u32) { + write_num_bytes!(u32, 4, n, buf, to_le); + } + + #[inline] + fn write_u64(buf: &mut [u8], n: u64) { + write_num_bytes!(u64, 8, n, buf, to_le); + } + + serde_if_integer128! { + #[inline] + fn write_u128(buf: &mut [u8], n: u128) { + write_num_bytes!(u128, 16, n, buf, to_le); + } + + #[inline] + fn read_u128(buf: &[u8]) -> u128 { + read_num_bytes!(u128, 16, buf, to_le) + } + } +} + +impl ByteOrder for BigEndian { + #[inline] + fn read_u16(buf: &[u8]) -> u16 { + read_num_bytes!(u16, 2, buf, to_be) + } + + #[inline] + fn read_u32(buf: &[u8]) -> u32 { + read_num_bytes!(u32, 4, buf, to_be) + } + + #[inline] + fn read_u64(buf: &[u8]) -> u64 { + read_num_bytes!(u64, 8, buf, to_be) + } + + #[inline] + fn write_u16(buf: &mut [u8], n: u16) { + write_num_bytes!(u16, 2, n, buf, to_be); + } + + #[inline] + fn write_u32(buf: &mut [u8], n: u32) { + write_num_bytes!(u32, 4, n, buf, to_be); + } + + #[inline] + fn write_u64(buf: &mut [u8], n: u64) { + write_num_bytes!(u64, 8, n, buf, to_be); + } + + serde_if_integer128! { + #[inline] + fn write_u128(buf: &mut [u8], n: u128) { + write_num_bytes!(u128, 16, n, buf, to_be); + } + + #[inline] + fn read_u128(buf: &[u8]) -> u128 { + read_num_bytes!(u128, 16, buf, to_be) + } + } +} + +pub trait ByteOrder: Clone + Copy { + fn read_u16(buf: &[u8]) -> u16; + + fn read_u32(buf: &[u8]) -> u32; + + fn read_u64(buf: &[u8]) -> u64; + + fn write_u16(buf: &mut [u8], n: u16); + + fn write_u32(buf: &mut [u8], n: u32); + + fn write_u64(buf: &mut [u8], n: u64); + + #[inline] + fn read_i16(buf: &[u8]) -> i16 { + Self::read_u16(buf) as i16 + } + + #[inline] + fn read_i32(buf: &[u8]) -> i32 { + Self::read_u32(buf) as i32 + } + + #[inline] + fn read_i64(buf: &[u8]) -> i64 { + Self::read_u64(buf) as i64 + } + + #[inline] + fn read_f32(buf: &[u8]) -> f32 { + unsafe { *(&Self::read_u32(buf) as *const u32 as *const f32) } + } + + #[inline] + fn read_f64(buf: &[u8]) -> f64 { + unsafe { *(&Self::read_u64(buf) as *const u64 as *const f64) } + } + + #[inline] + fn write_i16(buf: &mut [u8], n: i16) { + Self::write_u16(buf, n as u16) + } + + #[inline] + fn write_i32(buf: &mut [u8], n: i32) { + Self::write_u32(buf, n as u32) + } + + #[inline] + fn write_i64(buf: &mut [u8], n: i64) { + Self::write_u64(buf, n as u64) + } + + #[inline] + fn write_f32(buf: &mut [u8], n: f32) { + let n = unsafe { *(&n as *const f32 as *const u32) }; + Self::write_u32(buf, n) + } + + #[inline] + fn write_f64(buf: &mut [u8], n: f64) { + let n = unsafe { *(&n as *const f64 as *const u64) }; + Self::write_u64(buf, n) + } + + serde_if_integer128! { + fn read_u128(buf: &[u8]) -> u128; + fn write_u128(buf: &mut [u8], n: u128); + + #[inline] + fn read_i128(buf: &[u8]) -> i128 { + Self::read_u128(buf) as i128 + } + + #[inline] + fn write_i128(buf: &mut [u8], n: i128) { + Self::write_u128(buf, n as u128) + } + } +} + +pub trait ReadBytesExt: io::Read { + #[inline] + fn read_u8(&mut self) -> Result { + let mut buf = [0; 1]; + try!(self.read_exact(&mut buf)); + Ok(buf[0]) + } + + #[inline] + fn read_i8(&mut self) -> Result { + let mut buf = [0; 1]; + try!(self.read_exact(&mut buf)); + Ok(buf[0] as i8) + } + + #[inline] + fn read_u16(&mut self) -> Result { + let mut buf = [0; 2]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u16(&buf)) + } + + #[inline] + fn read_i16(&mut self) -> Result { + let mut buf = [0; 2]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i16(&buf)) + } + + #[inline] + fn read_u32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u32(&buf)) + } + + #[inline] + fn read_i32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i32(&buf)) + } + + #[inline] + fn read_u64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u64(&buf)) + } + + #[inline] + fn read_i64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i64(&buf)) + } + + #[inline] + fn read_f32(&mut self) -> Result { + let mut buf = [0; 4]; + try!(self.read_exact(&mut buf)); + Ok(T::read_f32(&buf)) + } + + #[inline] + fn read_f64(&mut self) -> Result { + let mut buf = [0; 8]; + try!(self.read_exact(&mut buf)); + Ok(T::read_f64(&buf)) + } + + serde_if_integer128! { + #[inline] + fn read_u128(&mut self) -> Result { + let mut buf = [0; 16]; + try!(self.read_exact(&mut buf)); + Ok(T::read_u128(&buf)) + } + + #[inline] + fn read_i128(&mut self) -> Result { + let mut buf = [0; 16]; + try!(self.read_exact(&mut buf)); + Ok(T::read_i128(&buf)) + } + } +} + +impl ReadBytesExt for R {} + +pub trait WriteBytesExt: io::Write { + #[inline] + fn write_u8(&mut self, n: u8) -> Result<()> { + self.write_all(&[n]) + } + + #[inline] + fn write_i8(&mut self, n: i8) -> Result<()> { + self.write_all(&[n as u8]) + } + + #[inline] + fn write_u16(&mut self, n: u16) -> Result<()> { + let mut buf = [0; 2]; + T::write_u16(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i16(&mut self, n: i16) -> Result<()> { + let mut buf = [0; 2]; + T::write_i16(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_u32(&mut self, n: u32) -> Result<()> { + let mut buf = [0; 4]; + T::write_u32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i32(&mut self, n: i32) -> Result<()> { + let mut buf = [0; 4]; + T::write_i32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_u64(&mut self, n: u64) -> Result<()> { + let mut buf = [0; 8]; + T::write_u64(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i64(&mut self, n: i64) -> Result<()> { + let mut buf = [0; 8]; + T::write_i64(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_f32(&mut self, n: f32) -> Result<()> { + let mut buf = [0; 4]; + T::write_f32(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_f64(&mut self, n: f64) -> Result<()> { + let mut buf = [0; 8]; + T::write_f64(&mut buf, n); + self.write_all(&buf) + } + + serde_if_integer128! { + #[inline] + fn write_u128(&mut self, n: u128) -> Result<()> { + let mut buf = [0; 16]; + T::write_u128(&mut buf, n); + self.write_all(&buf) + } + + #[inline] + fn write_i128(&mut self, n: i128) -> Result<()> { + let mut buf = [0; 16]; + T::write_i128(&mut buf, n); + self.write_all(&buf) + } + } +} + +impl WriteBytesExt for W {} diff --git a/vendor/bincode/src/config/endian.rs b/vendor/bincode/src/config/endian.rs new file mode 100644 index 000000000..2561620a2 --- /dev/null +++ b/vendor/bincode/src/config/endian.rs @@ -0,0 +1,27 @@ +pub trait BincodeByteOrder { + type Endian: ::byteorder::ByteOrder + 'static; +} + +/// Little-endian byte ordering. +#[derive(Copy, Clone)] +pub struct LittleEndian; + +/// Big-endian byte ordering. +#[derive(Copy, Clone)] +pub struct BigEndian; + +/// The native byte ordering of the current system. +#[derive(Copy, Clone)] +pub struct NativeEndian; + +impl BincodeByteOrder for LittleEndian { + type Endian = ::byteorder::LittleEndian; +} + +impl BincodeByteOrder for BigEndian { + type Endian = ::byteorder::BigEndian; +} + +impl BincodeByteOrder for NativeEndian { + type Endian = ::byteorder::NativeEndian; +} diff --git a/vendor/bincode/src/config/int.rs b/vendor/bincode/src/config/int.rs new file mode 100644 index 000000000..f716d1abd --- /dev/null +++ b/vendor/bincode/src/config/int.rs @@ -0,0 +1,682 @@ +use std::io::Write; +use std::mem::size_of; + +use super::Options; +use de::read::BincodeRead; +use error::{ErrorKind, Result}; + +pub trait IntEncoding { + /// Gets the size (in bytes) that a value would be serialized to. + fn u16_size(n: u16) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn u32_size(n: u32) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn u64_size(n: u64) -> u64; + + /// Gets the size (in bytes) that a value would be serialized to. + fn i16_size(n: i16) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn i32_size(n: i32) -> u64; + /// Gets the size (in bytes) that a value would be serialized to. + fn i64_size(n: i64) -> u64; + + #[inline(always)] + fn len_size(len: usize) -> u64 { + Self::u64_size(len as u64) + } + + /// Serializes a sequence length. + #[inline(always)] + fn serialize_len( + ser: &mut ::ser::Serializer, + len: usize, + ) -> Result<()> { + Self::serialize_u64(ser, len as u64) + } + + fn serialize_u16( + ser: &mut ::ser::Serializer, + val: u16, + ) -> Result<()>; + + fn serialize_u32( + ser: &mut ::ser::Serializer, + val: u32, + ) -> Result<()>; + + fn serialize_u64( + ser: &mut ::ser::Serializer, + val: u64, + ) -> Result<()>; + + fn serialize_i16( + ser: &mut ::ser::Serializer, + val: i16, + ) -> Result<()>; + + fn serialize_i32( + ser: &mut ::ser::Serializer, + val: i32, + ) -> Result<()>; + + fn serialize_i64( + ser: &mut ::ser::Serializer, + val: i64, + ) -> Result<()>; + + /// Deserializes a sequence length. + #[inline(always)] + fn deserialize_len<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + Self::deserialize_u64(de).and_then(cast_u64_to_usize) + } + + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result; + + serde_if_integer128! { + fn u128_size(v: u128) -> u64; + fn i128_size(v: i128) -> u64; + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()>; + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result; + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()>; + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result; + } +} + +/// Fixed-size integer encoding. +/// +/// * Fixed size integers are encoded directly +/// * Enum discriminants are encoded as u32 +/// * Lengths and usize are encoded as u64 +#[derive(Copy, Clone)] +pub struct FixintEncoding; + +/// Variable-size integer encoding (excepting [ui]8). +/// +/// Encoding an unsigned integer v (of any type excepting u8) works as follows: +/// +/// 1. If `u < 251`, encode it as a single byte with that value. +/// 2. If `251 <= u < 2**16`, encode it as a literal byte 251, followed by a u16 with value `u`. +/// 3. If `2**16 <= u < 2**32`, encode it as a literal byte 252, followed by a u32 with value `u`. +/// 4. If `2**32 <= u < 2**64`, encode it as a literal byte 253, followed by a u64 with value `u`. +/// 5. If `2**64 <= u < 2**128`, encode it as a literal byte 254, followed by a +/// u128 with value `u`. +/// +/// Then, for signed integers, we first convert to unsigned using the zigzag algorithm, +/// and then encode them as we do for unsigned integers generally. The reason we use this +/// algorithm is that it encodes those values which are close to zero in less bytes; the +/// obvious algorithm, where we encode the cast values, gives a very large encoding for all +/// negative values. +/// +/// The zigzag algorithm is defined as follows: +/// +/// ```ignore +/// fn zigzag(v: Signed) -> Unsigned { +/// match v { +/// 0 => 0, +/// v if v < 0 => |v| * 2 - 1 +/// v if v > 0 => v * 2 +/// } +/// } +/// ``` +/// +/// And works such that: +/// +/// ```ignore +/// assert_eq!(zigzag(0), 0); +/// assert_eq!(zigzag(-1), 1); +/// assert_eq!(zigzag(1), 2); +/// assert_eq!(zigzag(-2), 3); +/// assert_eq!(zigzag(2), 4); +/// assert_eq!(zigzag(i64::min_value()), u64::max_value()); +/// ``` +/// +/// Note that u256 and the like are unsupported by this format; if and when they are added to the +/// language, they may be supported via the extension point given by the 255 byte. +#[derive(Copy, Clone)] +pub struct VarintEncoding; + +const SINGLE_BYTE_MAX: u8 = 250; +const U16_BYTE: u8 = 251; +const U32_BYTE: u8 = 252; +const U64_BYTE: u8 = 253; +const U128_BYTE: u8 = 254; +const DESERIALIZE_EXTENSION_POINT_ERR: &str = r#" +Byte 255 is treated as an extension point; it should not be encoding anything. +Do you have a mismatched bincode version or configuration? +"#; + +impl VarintEncoding { + fn varint_size(n: u64) -> u64 { + if n <= SINGLE_BYTE_MAX as u64 { + 1 + } else if n <= u16::max_value() as u64 { + (1 + size_of::()) as u64 + } else if n <= u32::max_value() as u64 { + (1 + size_of::()) as u64 + } else { + (1 + size_of::()) as u64 + } + } + + #[inline(always)] + fn zigzag_encode(n: i64) -> u64 { + if n < 0 { + // let's avoid the edge case of i64::min_value() + // !n is equal to `-n - 1`, so this is: + // !n * 2 + 1 = 2(-n - 1) + 1 = -2n - 2 + 1 = -2n - 1 + !(n as u64) * 2 + 1 + } else { + (n as u64) * 2 + } + } + + #[inline(always)] + fn zigzag_decode(n: u64) -> i64 { + if n % 2 == 0 { + // positive number + (n / 2) as i64 + } else { + // negative number + // !m * 2 + 1 = n + // !m * 2 = n - 1 + // !m = (n - 1) / 2 + // m = !((n - 1) / 2) + // since we have n is odd, we have floor(n / 2) = floor((n - 1) / 2) + !(n / 2) as i64 + } + } + + fn serialize_varint( + ser: &mut ::ser::Serializer, + n: u64, + ) -> Result<()> { + if n <= SINGLE_BYTE_MAX as u64 { + ser.serialize_byte(n as u8) + } else if n <= u16::max_value() as u64 { + ser.serialize_byte(U16_BYTE)?; + ser.serialize_literal_u16(n as u16) + } else if n <= u32::max_value() as u64 { + ser.serialize_byte(U32_BYTE)?; + ser.serialize_literal_u32(n as u32) + } else { + ser.serialize_byte(U64_BYTE)?; + ser.serialize_literal_u64(n as u64) + } + } + + fn deserialize_varint<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + #[allow(ellipsis_inclusive_range_patterns)] + match de.deserialize_byte()? { + byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u64), + U16_BYTE => Ok(de.deserialize_literal_u16()? as u64), + U32_BYTE => Ok(de.deserialize_literal_u32()? as u64), + U64_BYTE => de.deserialize_literal_u64(), + U128_BYTE => Err(Box::new(ErrorKind::Custom( + "Invalid value (u128 range): you may have a version or configuration disagreement?" + .to_string(), + ))), + _ => Err(Box::new(ErrorKind::Custom( + DESERIALIZE_EXTENSION_POINT_ERR.to_string(), + ))), + } + } + + serde_if_integer128! { + // see zigzag_encode and zigzag_decode for implementation comments + #[inline(always)] + fn zigzag128_encode(n: i128) -> u128 { + if n < 0 { + !(n as u128) * 2 + 1 + } else { + (n as u128) * 2 + } + } + #[inline(always)] + fn zigzag128_decode(n: u128) -> i128 { + if n % 2 == 0 { + (n / 2) as i128 + } else { + !(n / 2) as i128 + } + } + + fn varint128_size(n: u128) -> u64 { + if n <= SINGLE_BYTE_MAX as u128 { + 1 + } else if n <= u16::max_value() as u128 { + (1 + size_of::()) as u64 + } else if n <= u32::max_value() as u128 { + (1 + size_of::()) as u64 + } else if n <= u64::max_value() as u128 { + (1 + size_of::()) as u64 + } else { + (1 + size_of::()) as u64 + } + } + + fn serialize_varint128( + ser: &mut ::ser::Serializer, + n: u128, + ) -> Result<()> { + if n <= SINGLE_BYTE_MAX as u128 { + ser.serialize_byte(n as u8) + } else if n <= u16::max_value() as u128 { + ser.serialize_byte(U16_BYTE)?; + ser.serialize_literal_u16(n as u16) + } else if n <= u32::max_value() as u128 { + ser.serialize_byte(U32_BYTE)?; + ser.serialize_literal_u32(n as u32) + } else if n <= u64::max_value() as u128 { + ser.serialize_byte(U64_BYTE)?; + ser.serialize_literal_u64(n as u64) + } else { + ser.serialize_byte(U128_BYTE)?; + ser.serialize_literal_u128(n) + } + } + + fn deserialize_varint128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::de::Deserializer, + ) -> Result { + #[allow(ellipsis_inclusive_range_patterns)] + match de.deserialize_byte()? { + byte @ 0...SINGLE_BYTE_MAX => Ok(byte as u128), + U16_BYTE => Ok(de.deserialize_literal_u16()? as u128), + U32_BYTE => Ok(de.deserialize_literal_u32()? as u128), + U64_BYTE => Ok(de.deserialize_literal_u64()? as u128), + U128_BYTE => de.deserialize_literal_u128(), + _ => Err(Box::new(ErrorKind::Custom(DESERIALIZE_EXTENSION_POINT_ERR.to_string()))), + } + } + } +} + +impl IntEncoding for FixintEncoding { + #[inline(always)] + fn u16_size(_: u16) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn u32_size(_: u32) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn u64_size(_: u64) -> u64 { + size_of::() as u64 + } + + #[inline(always)] + fn i16_size(_: i16) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn i32_size(_: i32) -> u64 { + size_of::() as u64 + } + #[inline(always)] + fn i64_size(_: i64) -> u64 { + size_of::() as u64 + } + + #[inline(always)] + fn serialize_u16(ser: &mut ::Serializer, val: u16) -> Result<()> { + ser.serialize_literal_u16(val) + } + #[inline(always)] + fn serialize_u32(ser: &mut ::Serializer, val: u32) -> Result<()> { + ser.serialize_literal_u32(val) + } + #[inline(always)] + fn serialize_u64(ser: &mut ::Serializer, val: u64) -> Result<()> { + ser.serialize_literal_u64(val) + } + + #[inline(always)] + fn serialize_i16(ser: &mut ::Serializer, val: i16) -> Result<()> { + ser.serialize_literal_u16(val as u16) + } + #[inline(always)] + fn serialize_i32(ser: &mut ::Serializer, val: i32) -> Result<()> { + ser.serialize_literal_u32(val as u32) + } + #[inline(always)] + fn serialize_i64(ser: &mut ::Serializer, val: i64) -> Result<()> { + ser.serialize_literal_u64(val as u64) + } + + #[inline(always)] + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u16() + } + #[inline(always)] + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u32() + } + #[inline(always)] + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u64() + } + + #[inline(always)] + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u16()? as i16) + } + #[inline(always)] + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u32()? as i32) + } + #[inline(always)] + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u64()? as i64) + } + + serde_if_integer128! { + #[inline(always)] + fn u128_size(_: u128) -> u64{ + size_of::() as u64 + } + #[inline(always)] + fn i128_size(_: i128) -> u64{ + size_of::() as u64 + } + + #[inline(always)] + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()> { + ser.serialize_literal_u128(val) + } + #[inline(always)] + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()> { + ser.serialize_literal_u128(val as u128) + } + #[inline(always)] + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + de.deserialize_literal_u128() + } + #[inline(always)] + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Ok(de.deserialize_literal_u128()? as i128) + } + } +} + +impl IntEncoding for VarintEncoding { + #[inline(always)] + fn u16_size(n: u16) -> u64 { + Self::varint_size(n as u64) + } + #[inline(always)] + fn u32_size(n: u32) -> u64 { + Self::varint_size(n as u64) + } + #[inline(always)] + fn u64_size(n: u64) -> u64 { + Self::varint_size(n) + } + + #[inline(always)] + fn i16_size(n: i16) -> u64 { + Self::varint_size(Self::zigzag_encode(n as i64)) + } + #[inline(always)] + fn i32_size(n: i32) -> u64 { + Self::varint_size(Self::zigzag_encode(n as i64)) + } + #[inline(always)] + fn i64_size(n: i64) -> u64 { + Self::varint_size(Self::zigzag_encode(n)) + } + + #[inline(always)] + fn serialize_u16(ser: &mut ::Serializer, val: u16) -> Result<()> { + Self::serialize_varint(ser, val as u64) + } + #[inline(always)] + fn serialize_u32(ser: &mut ::Serializer, val: u32) -> Result<()> { + Self::serialize_varint(ser, val as u64) + } + #[inline(always)] + fn serialize_u64(ser: &mut ::Serializer, val: u64) -> Result<()> { + Self::serialize_varint(ser, val) + } + + #[inline(always)] + fn serialize_i16(ser: &mut ::Serializer, val: i16) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val as i64)) + } + #[inline(always)] + fn serialize_i32(ser: &mut ::Serializer, val: i32) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val as i64)) + } + #[inline(always)] + fn serialize_i64(ser: &mut ::Serializer, val: i64) -> Result<()> { + Self::serialize_varint(ser, Self::zigzag_encode(val)) + } + + #[inline(always)] + fn deserialize_u16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).and_then(cast_u64_to_u16) + } + #[inline(always)] + fn deserialize_u32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).and_then(cast_u64_to_u32) + } + #[inline(always)] + fn deserialize_u64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + } + + #[inline(always)] + fn deserialize_i16<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + .map(Self::zigzag_decode) + .and_then(cast_i64_to_i16) + } + #[inline(always)] + fn deserialize_i32<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de) + .map(Self::zigzag_decode) + .and_then(cast_i64_to_i32) + } + #[inline(always)] + fn deserialize_i64<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint(de).map(Self::zigzag_decode) + } + + serde_if_integer128! { + #[inline(always)] + fn u128_size(n: u128) -> u64 { + Self::varint128_size(n) + } + #[inline(always)] + fn i128_size(n: i128) -> u64 { + Self::varint128_size(Self::zigzag128_encode(n)) + } + #[inline(always)] + fn serialize_u128( + ser: &mut ::Serializer, + val: u128, + ) -> Result<()> { + Self::serialize_varint128(ser, val) + } + #[inline(always)] + fn serialize_i128( + ser: &mut ::Serializer, + val: i128, + ) -> Result<()> { + Self::serialize_varint128(ser, Self::zigzag128_encode(val)) + } + #[inline(always)] + fn deserialize_u128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint128(de) + } + #[inline(always)] + fn deserialize_i128<'de, R: BincodeRead<'de>, O: Options>( + de: &mut ::Deserializer, + ) -> Result { + Self::deserialize_varint128(de).map(Self::zigzag128_decode) + } + } +} + +fn cast_u64_to_usize(n: u64) -> Result { + if n <= usize::max_value() as u64 { + Ok(n as usize) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid size {}: sizes must fit in a usize (0 to {})", + n, + usize::max_value() + )))) + } +} +fn cast_u64_to_u32(n: u64) -> Result { + if n <= u32::max_value() as u64 { + Ok(n as u32) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid u32 {}: you may have a version disagreement?", + n, + )))) + } +} +fn cast_u64_to_u16(n: u64) -> Result { + if n <= u16::max_value() as u64 { + Ok(n as u16) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid u16 {}: you may have a version disagreement?", + n, + )))) + } +} + +fn cast_i64_to_i32(n: i64) -> Result { + if n <= i32::max_value() as i64 && n >= i32::min_value() as i64 { + Ok(n as i32) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid i32 {}: you may have a version disagreement?", + n, + )))) + } +} + +fn cast_i64_to_i16(n: i64) -> Result { + if n <= i16::max_value() as i64 && n >= i16::min_value() as i64 { + Ok(n as i16) + } else { + Err(Box::new(ErrorKind::Custom(format!( + "Invalid i16 {}: you may have a version disagreement?", + n, + )))) + } +} + +#[cfg(test)] +mod test { + use super::VarintEncoding; + + #[test] + fn test_zigzag_encode() { + let zigzag = VarintEncoding::zigzag_encode; + + assert_eq!(zigzag(0), 0); + for x in 1..512 { + assert_eq!(zigzag(x), (x as u64) * 2); + assert_eq!(zigzag(-x), (x as u64) * 2 - 1); + } + } + + #[test] + fn test_zigzag_decode() { + // zigzag' + let zigzagp = VarintEncoding::zigzag_decode; + for x in (0..512).map(|x| x * 2) { + assert_eq!(zigzagp(x), x as i64 / 2); + assert_eq!(zigzagp(x + 1), -(x as i64) / 2 - 1); + } + } + + #[test] + fn test_zigzag_edge_cases() { + let (zigzag, zigzagp) = (VarintEncoding::zigzag_encode, VarintEncoding::zigzag_decode); + + assert_eq!(zigzag(i64::max_value()), u64::max_value() - 1); + assert_eq!(zigzag(i64::min_value()), u64::max_value()); + + assert_eq!(zigzagp(u64::max_value() - 1), i64::max_value()); + assert_eq!(zigzagp(u64::max_value()), i64::min_value()); + } +} diff --git a/vendor/bincode/src/config/legacy.rs b/vendor/bincode/src/config/legacy.rs new file mode 100644 index 000000000..ec5c7f044 --- /dev/null +++ b/vendor/bincode/src/config/legacy.rs @@ -0,0 +1,253 @@ +use std::io::{Read, Write}; + +use self::EndianOption::*; +use self::LimitOption::*; +use super::{DefaultOptions, Options}; +use de::read::BincodeRead; +use error::Result; +use serde; + +/// A configuration builder whose options Bincode will use +/// while serializing and deserializing. +/// +/// ### Options +/// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian* +/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited* +/// +/// ### Byte Limit Details +/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode +/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long. +/// +/// 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. +#[derive(Clone, Debug)] +#[deprecated( + since = "1.3.0", + note = "please use the `DefaultOptions`/`Options` system instead" +)] +pub struct Config { + limit: LimitOption, + endian: EndianOption, +} + +#[derive(Clone, Copy, Debug)] +enum LimitOption { + Unlimited, + Limited(u64), +} + +#[derive(Clone, Copy, Debug)] +enum EndianOption { + Big, + Little, + Native, +} + +macro_rules! config_map { + ($self:expr, $opts:ident => $call:expr) => { + match ($self.limit, $self.endian) { + (Unlimited, Little) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_little_endian(); + $call + } + (Unlimited, Big) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_big_endian(); + $call + } + (Unlimited, Native) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_no_limit() + .with_native_endian(); + $call + } + + (Limited(l), Little) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_little_endian(); + $call + } + (Limited(l), Big) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_big_endian(); + $call + } + (Limited(l), Native) => { + let $opts = DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .with_limit(l) + .with_native_endian(); + $call + } + } + }; +} + +impl Config { + #[inline(always)] + pub(crate) fn new() -> Config { + Config { + limit: LimitOption::Unlimited, + endian: EndianOption::Little, + } + } + + /// Sets the byte limit to be unlimited. + /// This is the default. + #[inline(always)] + pub fn no_limit(&mut self) -> &mut Self { + self.limit = LimitOption::Unlimited; + self + } + + /// Sets the byte limit to `limit`. + #[inline(always)] + pub fn limit(&mut self, limit: u64) -> &mut Self { + self.limit = LimitOption::Limited(limit); + self + } + + /// Sets the endianness to little-endian + /// This is the default. + #[inline(always)] + pub fn little_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Little; + self + } + + /// Sets the endianness to big-endian + #[inline(always)] + pub fn big_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Big; + self + } + + /// Sets the endianness to the the machine-native endianness + #[inline(always)] + pub fn native_endian(&mut self) -> &mut Self { + self.endian = EndianOption::Native; + self + } + + /// Serializes a serializable object into a `Vec` of bytes using this configuration + #[inline(always)] + pub fn serialize(&self, t: &T) -> Result> { + config_map!(self, opts => ::internal::serialize(t, opts)) + } + + /// Returns the size that an object would be if serialized using Bincode with this configuration + #[inline(always)] + pub fn serialized_size(&self, t: &T) -> Result { + config_map!(self, opts => ::internal::serialized_size(t, opts)) + } + + /// Serializes an object directly into a `Writer` using this configuration + /// + /// If the serialization would take more bytes than allowed by the size limit, an error + /// is returned and *no bytes* will be written into the `Writer` + #[inline(always)] + pub fn serialize_into( + &self, + w: W, + t: &T, + ) -> Result<()> { + config_map!(self, opts => ::internal::serialize_into(w, t, opts)) + } + + /// Deserializes a slice of bytes into an instance of `T` using this configuration + #[inline(always)] + pub fn deserialize<'a, T: serde::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result { + config_map!(self, opts => ::internal::deserialize(bytes, opts)) + } + + /// TODO: document + #[doc(hidden)] + #[inline(always)] + pub fn deserialize_in_place<'a, R, T>(&self, reader: R, place: &mut T) -> Result<()> + where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + { + config_map!(self, opts => ::internal::deserialize_in_place(reader, opts, place)) + } + + /// Deserializes a slice of bytes with state `seed` using this configuration. + #[inline(always)] + pub fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( + &self, + seed: T, + bytes: &'a [u8], + ) -> Result { + config_map!(self, opts => ::internal::deserialize_seed(seed, bytes, opts)) + } + + /// Deserializes an object directly from a `Read`er using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from( + &self, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from(reader, opts)) + } + + /// Deserializes an object directly from a `Read`er with state `seed` using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_seed(seed, reader, opts)) + } + + /// Deserializes an object from a custom `BincodeRead`er using the default configuration. + /// It is highly recommended to use `deserialize_from` unless you need to implement + /// `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( + &self, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_custom(reader, opts)) + } + + /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default + /// configuration. It is highly recommended to use `deserialize_from` unless you need to + /// implement `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + pub fn deserialize_from_custom_seed< + 'a, + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + >( + &self, + seed: T, + reader: R, + ) -> Result { + config_map!(self, opts => ::internal::deserialize_from_custom_seed(seed, reader, opts)) + } +} diff --git a/vendor/bincode/src/config/limit.rs b/vendor/bincode/src/config/limit.rs new file mode 100644 index 000000000..477229830 --- /dev/null +++ b/vendor/bincode/src/config/limit.rs @@ -0,0 +1,49 @@ +use error::{ErrorKind, Result}; + +/// A trait for stopping serialization and deserialization when a certain limit has been reached. +pub trait SizeLimit { + /// Tells the SizeLimit that a certain number of bytes has been + /// read or written. Returns Err if the limit has been exceeded. + fn add(&mut self, n: u64) -> Result<()>; + /// Returns the hard limit (if one exists) + fn limit(&self) -> Option; +} + +/// A SizeLimit that restricts serialized or deserialized messages from +/// exceeding a certain byte length. +#[derive(Copy, Clone)] +pub struct Bounded(pub u64); + +/// A SizeLimit without a limit! +/// Use this if you don't care about the size of encoded or decoded messages. +#[derive(Copy, Clone)] +pub struct Infinite; + +impl SizeLimit for Bounded { + #[inline(always)] + fn add(&mut self, n: u64) -> Result<()> { + if self.0 >= n { + self.0 -= n; + Ok(()) + } else { + Err(Box::new(ErrorKind::SizeLimit)) + } + } + + #[inline(always)] + fn limit(&self) -> Option { + Some(self.0) + } +} + +impl SizeLimit for Infinite { + #[inline(always)] + fn add(&mut self, _: u64) -> Result<()> { + Ok(()) + } + + #[inline(always)] + fn limit(&self) -> Option { + None + } +} diff --git a/vendor/bincode/src/config/mod.rs b/vendor/bincode/src/config/mod.rs new file mode 100644 index 000000000..33fa92008 --- /dev/null +++ b/vendor/bincode/src/config/mod.rs @@ -0,0 +1,408 @@ +//! `bincode` uses a Builder-pattern to configure the Serializers and Deserializers in this +//! crate. This means that if you need to customize the behavior of `bincode`, you should create an +//! instance of the `DefaultOptions` struct: +//! +//! ```rust +//! use bincode::Options; +//! let my_options = bincode::DefaultOptions::new(); +//! ``` +//! +//! # Options Struct vs bincode functions +//! +//! Due to historical reasons, the default options used by the `serialize()` and `deserialize()` +//! family of functions are different than the default options created by the `DefaultOptions` struct: +//! +//! | | Byte limit | Endianness | Int Encoding | Trailing Behavior | +//! |----------|------------|------------|--------------|-------------------| +//! | struct | Unlimited | Little | Varint | Reject | +//! | function | Unlimited | Little | Fixint | Allow | +//! +//! This means that if you want to use the `Serialize` / `Deserialize` structs with the same +//! settings as the functions, you should adjust the `DefaultOptions` struct like so: +//! +//! ```rust +//! use bincode::Options; +//! let my_options = bincode::DefaultOptions::new() +//! .with_fixint_encoding() +//! .allow_trailing_bytes(); +//! ``` + +use de::read::BincodeRead; +use error::Result; +use serde; +use std::io::{Read, Write}; +use std::marker::PhantomData; + +pub(crate) use self::endian::BincodeByteOrder; +pub(crate) use self::int::IntEncoding; +pub(crate) use self::internal::*; +pub(crate) use self::limit::SizeLimit; +pub(crate) use self::trailing::TrailingBytes; + +pub use self::endian::{BigEndian, LittleEndian, NativeEndian}; +pub use self::int::{FixintEncoding, VarintEncoding}; +pub use self::legacy::*; +pub use self::limit::{Bounded, Infinite}; +pub use self::trailing::{AllowTrailing, RejectTrailing}; + +mod endian; +mod int; +mod legacy; +mod limit; +mod trailing; + +/// The default options for bincode serialization/deserialization. +/// +/// ### Defaults +/// By default bincode will use little-endian encoding for multi-byte integers, and will not +/// limit the number of serialized/deserialized bytes. +/// +/// ### Configuring `DefaultOptions` +/// +/// `DefaultOptions` implements the [Options] trait, which means it exposes functions to change the behavior of bincode. +/// +/// For example, if you wanted to limit the bincode deserializer to 1 kilobyte of user input: +/// +/// ```rust +/// use bincode::Options; +/// let my_options = bincode::DefaultOptions::new().with_limit(1024); +/// ``` +/// +/// ### DefaultOptions struct vs. functions +/// +/// The default configuration used by this struct is not the same as that used by the bincode +/// helper functions in the root of this crate. See the +/// [config](index.html#options-struct-vs-bincode-functions) module for more details +#[derive(Copy, Clone)] +pub struct DefaultOptions(Infinite); + +impl DefaultOptions { + /// Get a default configuration object. + /// + /// ### Default Configuration: + /// + /// | Byte limit | Endianness | Int Encoding | Trailing Behavior | + /// |------------|------------|--------------|-------------------| + /// | Unlimited | Little | Varint | Reject | + pub fn new() -> DefaultOptions { + DefaultOptions(Infinite) + } +} + +impl Default for DefaultOptions { + fn default() -> Self { + Self::new() + } +} + +impl InternalOptions for DefaultOptions { + type Limit = Infinite; + type Endian = LittleEndian; + type IntEncoding = VarintEncoding; + type Trailing = RejectTrailing; + + #[inline(always)] + fn limit(&mut self) -> &mut Infinite { + &mut self.0 + } +} + +/// A configuration builder trait whose options Bincode will use +/// while serializing and deserializing. +/// +/// ### Options +/// Endianness: The endianness with which multi-byte integers will be read/written. *default: little endian* +/// +/// Limit: The maximum number of bytes that will be read/written in a bincode serialize/deserialize. *default: unlimited* +/// +/// Int Encoding: The encoding used for numbers, enum discriminants, and lengths. *default: varint* +/// +/// Trailing Behavior: The behavior when there are trailing bytes left over in a slice after deserialization. *default: reject* +/// +/// ### Byte Limit Details +/// The purpose of byte-limiting is to prevent Denial-Of-Service attacks whereby malicious attackers get bincode +/// deserialization to crash your process by allocating too much memory or keeping a connection open for too long. +/// +/// 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. +pub trait Options: InternalOptions + Sized { + /// Sets the byte limit to be unlimited. + /// This is the default. + fn with_no_limit(self) -> WithOtherLimit { + WithOtherLimit::new(self, Infinite) + } + + /// Sets the byte limit to `limit`. + fn with_limit(self, limit: u64) -> WithOtherLimit { + WithOtherLimit::new(self, Bounded(limit)) + } + + /// Sets the endianness to little-endian + /// This is the default. + fn with_little_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the endianness to big-endian + fn with_big_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the endianness to the the machine-native endianness + fn with_native_endian(self) -> WithOtherEndian { + WithOtherEndian::new(self) + } + + /// Sets the length encoding to varint + fn with_varint_encoding(self) -> WithOtherIntEncoding { + WithOtherIntEncoding::new(self) + } + + /// Sets the length encoding to be fixed + fn with_fixint_encoding(self) -> WithOtherIntEncoding { + WithOtherIntEncoding::new(self) + } + + /// Sets the deserializer to reject trailing bytes + fn reject_trailing_bytes(self) -> WithOtherTrailing { + WithOtherTrailing::new(self) + } + + /// Sets the deserializer to allow trailing bytes + fn allow_trailing_bytes(self) -> WithOtherTrailing { + WithOtherTrailing::new(self) + } + + /// Serializes a serializable object into a `Vec` of bytes using this configuration + #[inline(always)] + fn serialize(self, t: &S) -> Result> { + ::internal::serialize(t, self) + } + + /// Returns the size that an object would be if serialized using Bincode with this configuration + #[inline(always)] + fn serialized_size(self, t: &T) -> Result { + ::internal::serialized_size(t, self) + } + + /// Serializes an object directly into a `Writer` using this configuration + /// + /// If the serialization would take more bytes than allowed by the size limit, an error + /// is returned and *no bytes* will be written into the `Writer` + #[inline(always)] + fn serialize_into(self, w: W, t: &T) -> Result<()> { + ::internal::serialize_into(w, t, self) + } + + /// Deserializes a slice of bytes into an instance of `T` using this configuration + #[inline(always)] + fn deserialize<'a, T: serde::Deserialize<'a>>(self, bytes: &'a [u8]) -> Result { + ::internal::deserialize(bytes, self) + } + + /// TODO: document + #[doc(hidden)] + #[inline(always)] + fn deserialize_in_place<'a, R, T>(self, reader: R, place: &mut T) -> Result<()> + where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + { + ::internal::deserialize_in_place(reader, self, place) + } + + /// Deserializes a slice of bytes with state `seed` using this configuration. + #[inline(always)] + fn deserialize_seed<'a, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + bytes: &'a [u8], + ) -> Result { + ::internal::deserialize_seed(seed, bytes, self) + } + + /// Deserializes an object directly from a `Read`er using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from(self, reader: R) -> Result { + ::internal::deserialize_from(reader, self) + } + + /// Deserializes an object directly from a `Read`er with state `seed` using this configuration + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_seed<'a, R: Read, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + reader: R, + ) -> Result { + ::internal::deserialize_from_seed(seed, reader, self) + } + + /// Deserializes an object from a custom `BincodeRead`er using the default configuration. + /// It is highly recommended to use `deserialize_from` unless you need to implement + /// `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_custom<'a, R: BincodeRead<'a>, T: serde::de::DeserializeOwned>( + self, + reader: R, + ) -> Result { + ::internal::deserialize_from_custom(reader, self) + } + + /// Deserializes an object from a custom `BincodeRead`er with state `seed` using the default + /// configuration. It is highly recommended to use `deserialize_from` unless you need to + /// implement `BincodeRead` for performance reasons. + /// + /// If this returns an `Error`, `reader` may be in an invalid state. + #[inline(always)] + fn deserialize_from_custom_seed<'a, R: BincodeRead<'a>, T: serde::de::DeserializeSeed<'a>>( + self, + seed: T, + reader: R, + ) -> Result { + ::internal::deserialize_from_custom_seed(seed, reader, self) + } +} + +impl Options for T {} + +/// A configuration struct with a user-specified byte limit +#[derive(Clone, Copy)] +pub struct WithOtherLimit { + _options: O, + pub(crate) new_limit: L, +} + +/// A configuration struct with a user-specified endian order +#[derive(Clone, Copy)] +pub struct WithOtherEndian { + options: O, + _endian: PhantomData, +} + +/// A configuration struct with a user-specified length encoding +#[derive(Clone, Copy)] +pub struct WithOtherIntEncoding { + options: O, + _length: PhantomData, +} + +/// A configuration struct with a user-specified trailing bytes behavior. +#[derive(Clone, Copy)] +pub struct WithOtherTrailing { + options: O, + _trailing: PhantomData, +} + +impl WithOtherLimit { + #[inline(always)] + pub(crate) fn new(options: O, limit: L) -> WithOtherLimit { + WithOtherLimit { + _options: options, + new_limit: limit, + } + } +} + +impl WithOtherEndian { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherEndian { + WithOtherEndian { + options, + _endian: PhantomData, + } + } +} + +impl WithOtherIntEncoding { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherIntEncoding { + WithOtherIntEncoding { + options, + _length: PhantomData, + } + } +} + +impl WithOtherTrailing { + #[inline(always)] + pub(crate) fn new(options: O) -> WithOtherTrailing { + WithOtherTrailing { + options, + _trailing: PhantomData, + } + } +} + +impl InternalOptions for WithOtherEndian { + type Limit = O::Limit; + type Endian = E; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + #[inline(always)] + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +impl InternalOptions for WithOtherLimit { + type Limit = L; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + fn limit(&mut self) -> &mut L { + &mut self.new_limit + } +} + +impl InternalOptions for WithOtherIntEncoding { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = I; + type Trailing = O::Trailing; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +impl InternalOptions for WithOtherTrailing { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = T; + + fn limit(&mut self) -> &mut O::Limit { + self.options.limit() + } +} + +mod internal { + use super::*; + + pub trait InternalOptions { + type Limit: SizeLimit + 'static; + type Endian: BincodeByteOrder + 'static; + type IntEncoding: IntEncoding + 'static; + type Trailing: TrailingBytes + 'static; + + fn limit(&mut self) -> &mut Self::Limit; + } + + impl<'a, O: InternalOptions> InternalOptions for &'a mut O { + type Limit = O::Limit; + type Endian = O::Endian; + type IntEncoding = O::IntEncoding; + type Trailing = O::Trailing; + + #[inline(always)] + fn limit(&mut self) -> &mut Self::Limit { + (*self).limit() + } + } +} diff --git a/vendor/bincode/src/config/trailing.rs b/vendor/bincode/src/config/trailing.rs new file mode 100644 index 000000000..6052fc7d7 --- /dev/null +++ b/vendor/bincode/src/config/trailing.rs @@ -0,0 +1,37 @@ +use de::read::SliceReader; +use {ErrorKind, Result}; + +/// A trait for erroring deserialization if not all bytes were read. +pub trait TrailingBytes { + /// Checks a given slice reader to determine if deserialization used all bytes in the slice. + fn check_end(reader: &SliceReader) -> Result<()>; +} + +/// A TrailingBytes config that will allow trailing bytes in slices after deserialization. +#[derive(Copy, Clone)] +pub struct AllowTrailing; + +/// A TrailingBytes config that will cause bincode to produce an error if bytes are left over in the slice when deserialization is complete. + +#[derive(Copy, Clone)] +pub struct RejectTrailing; + +impl TrailingBytes for AllowTrailing { + #[inline(always)] + fn check_end(_reader: &SliceReader) -> Result<()> { + Ok(()) + } +} + +impl TrailingBytes for RejectTrailing { + #[inline(always)] + fn check_end(reader: &SliceReader) -> Result<()> { + if reader.is_finished() { + Ok(()) + } else { + Err(Box::new(ErrorKind::Custom( + "Slice had bytes remaining after deserialization".to_string(), + ))) + } + } +} diff --git a/vendor/bincode/src/de/mod.rs b/vendor/bincode/src/de/mod.rs new file mode 100644 index 000000000..7b2bdf528 --- /dev/null +++ b/vendor/bincode/src/de/mod.rs @@ -0,0 +1,515 @@ +use config::{BincodeByteOrder, Options}; +use std::io::Read; + +use self::read::{BincodeRead, IoReader, SliceReader}; +use byteorder::ReadBytesExt; +use config::{IntEncoding, SizeLimit}; +use serde; +use serde::de::Error as DeError; +use serde::de::IntoDeserializer; +use {Error, ErrorKind, Result}; + +/// Specialized ways to read data into bincode. +pub mod read; + +/// A Deserializer that reads bytes from a buffer. +/// +/// This struct should rarely be used. +/// In most cases, prefer the `deserialize_from` function. +/// +/// The ByteOrder that is chosen will impact the endianness that +/// is used to read integers out of the reader. +/// +/// ```ignore +/// let d = Deserializer::new(&mut some_reader, SizeLimit::new()); +/// serde::Deserialize::deserialize(&mut deserializer); +/// let bytes_read = d.bytes_read(); +/// ``` +pub struct Deserializer { + pub(crate) reader: R, + options: O, +} + +macro_rules! impl_deserialize_literal { + ($name:ident : $ty:ty = $read:ident()) => { + #[inline] + pub(crate) fn $name(&mut self) -> Result<$ty> { + self.read_literal_type::<$ty>()?; + self.reader + .$read::<::Endian>() + .map_err(Into::into) + } + }; +} + +impl<'de, IR: Read, O: Options> Deserializer, O> { + /// Creates a new Deserializer with a given `Read`er and options. + pub fn with_reader(r: IR, options: O) -> Self { + Deserializer { + reader: IoReader::new(r), + options, + } + } +} + +impl<'de, O: Options> Deserializer, O> { + /// Creates a new Deserializer that will read from the given slice. + pub fn from_slice(slice: &'de [u8], options: O) -> Self { + Deserializer { + reader: SliceReader::new(slice), + options, + } + } +} + +impl<'de, R: BincodeRead<'de>, O: Options> Deserializer { + /// Creates a new Deserializer with the given `BincodeRead`er + pub fn with_bincode_read(r: R, options: O) -> Deserializer { + Deserializer { reader: r, options } + } + + pub(crate) fn deserialize_byte(&mut self) -> Result { + self.read_literal_type::()?; + self.reader.read_u8().map_err(Into::into) + } + + impl_deserialize_literal! { deserialize_literal_u16 : u16 = read_u16() } + impl_deserialize_literal! { deserialize_literal_u32 : u32 = read_u32() } + impl_deserialize_literal! { deserialize_literal_u64 : u64 = read_u64() } + + serde_if_integer128! { + impl_deserialize_literal! { deserialize_literal_u128 : u128 = read_u128() } + } + + fn read_bytes(&mut self, count: u64) -> Result<()> { + self.options.limit().add(count) + } + + fn read_literal_type(&mut self) -> Result<()> { + use std::mem::size_of; + self.read_bytes(size_of::() as u64) + } + + fn read_vec(&mut self) -> Result> { + let len = O::IntEncoding::deserialize_len(self)?; + self.read_bytes(len as u64)?; + self.reader.get_byte_buffer(len) + } + + fn read_string(&mut self) -> Result { + let vec = self.read_vec()?; + String::from_utf8(vec).map_err(|e| ErrorKind::InvalidUtf8Encoding(e.utf8_error()).into()) + } +} + +macro_rules! impl_deserialize_int { + ($name:ident = $visitor_method:ident ($dser_method:ident)) => { + #[inline] + fn $name(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.$visitor_method(O::IntEncoding::$dser_method(self)?) + } + }; +} + +impl<'de, 'a, R, O> serde::Deserializer<'de> for &'a mut Deserializer +where + R: BincodeRead<'de>, + O: Options, +{ + type Error = Error; + + #[inline] + fn deserialize_any(self, _visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + Err(Box::new(ErrorKind::DeserializeAnyNotSupported)) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + match self.deserialize_byte()? { + 1 => visitor.visit_bool(true), + 0 => visitor.visit_bool(false), + value => Err(ErrorKind::InvalidBoolEncoding(value).into()), + } + } + + impl_deserialize_int!(deserialize_u16 = visit_u16(deserialize_u16)); + impl_deserialize_int!(deserialize_u32 = visit_u32(deserialize_u32)); + impl_deserialize_int!(deserialize_u64 = visit_u64(deserialize_u64)); + impl_deserialize_int!(deserialize_i16 = visit_i16(deserialize_i16)); + impl_deserialize_int!(deserialize_i32 = visit_i32(deserialize_i32)); + impl_deserialize_int!(deserialize_i64 = visit_i64(deserialize_i64)); + + fn deserialize_f32(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + self.read_literal_type::()?; + let value = self + .reader + .read_f32::<::Endian>()?; + visitor.visit_f32(value) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + self.read_literal_type::()?; + let value = self + .reader + .read_f64::<::Endian>()?; + visitor.visit_f64(value) + } + + serde_if_integer128! { + impl_deserialize_int!(deserialize_u128 = visit_u128(deserialize_u128)); + impl_deserialize_int!(deserialize_i128 = visit_i128(deserialize_i128)); + } + + #[inline] + fn deserialize_u8(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_u8(self.deserialize_byte()? as u8) + } + + #[inline] + fn deserialize_i8(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_i8(self.deserialize_byte()? as i8) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + use std::str; + + let error = || ErrorKind::InvalidCharEncoding.into(); + + let mut buf = [0u8; 4]; + + // Look at the first byte to see how many bytes must be read + self.reader.read_exact(&mut buf[..1])?; + let width = utf8_char_width(buf[0]); + if width == 1 { + return visitor.visit_char(buf[0] as char); + } + if width == 0 { + return Err(error()); + } + + if self.reader.read_exact(&mut buf[1..width]).is_err() { + return Err(error()); + } + + let res = str::from_utf8(&buf[..width]) + .ok() + .and_then(|s| s.chars().next()) + .ok_or_else(error)?; + visitor.visit_char(res) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let len = O::IntEncoding::deserialize_len(self)?; + self.read_bytes(len as u64)?; + self.reader.forward_read_str(len, visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_string(self.read_string()?) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let len = O::IntEncoding::deserialize_len(self)?; + self.read_bytes(len as u64)?; + self.reader.forward_read_bytes(len, visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_byte_buf(self.read_vec()?) + } + + fn deserialize_enum( + self, + _enum: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde::de::Visitor<'de>, + { + impl<'de, 'a, R: 'a, O> serde::de::EnumAccess<'de> for &'a mut Deserializer + where + R: BincodeRead<'de>, + O: Options, + { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> + where + V: serde::de::DeserializeSeed<'de>, + { + let idx: u32 = O::IntEncoding::deserialize_u32(self)?; + let val: Result<_> = seed.deserialize(idx.into_deserializer()); + Ok((val?, self)) + } + } + + visitor.visit_enum(self) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + struct Access<'a, R: Read + 'a, O: Options + 'a> { + deserializer: &'a mut Deserializer, + len: usize, + } + + impl<'de, 'a, 'b: 'a, R: BincodeRead<'de> + 'b, O: Options> serde::de::SeqAccess<'de> + for Access<'a, R, O> + { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result> + where + T: serde::de::DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let value = + serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?; + Ok(Some(value)) + } else { + Ok(None) + } + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + visitor.visit_seq(Access { + deserializer: self, + len, + }) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let value: u8 = serde::de::Deserialize::deserialize(&mut *self)?; + match value { + 0 => visitor.visit_none(), + 1 => visitor.visit_some(&mut *self), + v => Err(ErrorKind::InvalidTagEncoding(v as usize).into()), + } + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let len = O::IntEncoding::deserialize_len(self)?; + + self.deserialize_tuple(len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + struct Access<'a, R: Read + 'a, O: Options + 'a> { + deserializer: &'a mut Deserializer, + len: usize, + } + + impl<'de, 'a, 'b: 'a, R: BincodeRead<'de> + 'b, O: Options> serde::de::MapAccess<'de> + for Access<'a, R, O> + { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result> + where + K: serde::de::DeserializeSeed<'de>, + { + if self.len > 0 { + self.len -= 1; + let key = + serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?; + Ok(Some(key)) + } else { + Ok(None) + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: serde::de::DeserializeSeed<'de>, + { + let value = serde::de::DeserializeSeed::deserialize(seed, &mut *self.deserializer)?; + Ok(value) + } + + fn size_hint(&self) -> Option { + Some(self.len) + } + } + + let len = O::IntEncoding::deserialize_len(self)?; + + visitor.visit_map(Access { + deserializer: self, + len, + }) + } + + fn deserialize_struct( + self, + _name: &str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: serde::de::Visitor<'de>, + { + self.deserialize_tuple(fields.len(), visitor) + } + + fn deserialize_identifier(self, _visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let message = "Bincode does not support Deserializer::deserialize_identifier"; + Err(Error::custom(message)) + } + + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + visitor.visit_unit() + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: serde::de::Visitor<'de>, + { + self.deserialize_tuple(len, visitor) + } + + fn deserialize_ignored_any(self, _visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + let message = "Bincode does not support Deserializer::deserialize_ignored_any"; + Err(Error::custom(message)) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +impl<'de, 'a, R, O> serde::de::VariantAccess<'de> for &'a mut Deserializer +where + R: BincodeRead<'de>, + O: Options, +{ + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: serde::de::DeserializeSeed<'de>, + { + serde::de::DeserializeSeed::deserialize(seed, self) + } + + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + serde::de::Deserializer::deserialize_tuple(self, len, visitor) + } + + fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + serde::de::Deserializer::deserialize_tuple(self, fields.len(), visitor) + } +} +static UTF8_CHAR_WIDTH: [u8; 256] = [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x1F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x3F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x5F + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, // 0x7F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 0x9F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // 0xBF + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, // 0xDF + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF +]; + +// This function is a copy of core::str::utf8_char_width +fn utf8_char_width(b: u8) -> usize { + UTF8_CHAR_WIDTH[b as usize] as usize +} diff --git a/vendor/bincode/src/de/read.rs b/vendor/bincode/src/de/read.rs new file mode 100644 index 000000000..08b76adc9 --- /dev/null +++ b/vendor/bincode/src/de/read.rs @@ -0,0 +1,202 @@ +use error::Result; +use serde; +use std::io; + +/// An optional Read trait for advanced Bincode usage. +/// +/// It is highly recommended to use bincode with `io::Read` or `&[u8]` before +/// implementing a custom `BincodeRead`. +/// +/// The forward_read_* methods are necessary because some byte sources want +/// to pass a long-lived borrow to the visitor and others want to pass a +/// transient slice. +pub trait BincodeRead<'storage>: io::Read { + /// Check that the next `length` bytes are a valid string and pass + /// it on to the serde reader. + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>; + + /// Transfer ownership of the next `length` bytes to the caller. + fn get_byte_buffer(&mut self, length: usize) -> Result>; + + /// Pass a slice of the next `length` bytes on to the serde reader. + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>; +} + +/// A BincodeRead implementation for byte slices +pub struct SliceReader<'storage> { + slice: &'storage [u8], +} + +/// A BincodeRead implementation for `io::Read`ers +pub struct IoReader { + reader: R, + temp_buffer: Vec, +} + +impl<'storage> SliceReader<'storage> { + /// Constructs a slice reader + pub(crate) fn new(bytes: &'storage [u8]) -> SliceReader<'storage> { + SliceReader { slice: bytes } + } + + #[inline(always)] + fn get_byte_slice(&mut self, length: usize) -> Result<&'storage [u8]> { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + let (read_slice, remaining) = self.slice.split_at(length); + self.slice = remaining; + Ok(read_slice) + } + + pub(crate) fn is_finished(&self) -> bool { + self.slice.is_empty() + } +} + +impl IoReader { + /// Constructs an IoReadReader + pub(crate) fn new(r: R) -> IoReader { + IoReader { + reader: r, + temp_buffer: vec![], + } + } +} + +impl<'storage> io::Read for SliceReader<'storage> { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result { + if out.len() > self.slice.len() { + return Err(io::ErrorKind::UnexpectedEof.into()); + } + let (read_slice, remaining) = self.slice.split_at(out.len()); + out.copy_from_slice(read_slice); + self.slice = remaining; + + Ok(out.len()) + } + + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + self.read(out).map(|_| ()) + } +} + +impl io::Read for IoReader { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result { + self.reader.read(out) + } + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + self.reader.read_exact(out) + } +} + +impl<'storage> SliceReader<'storage> { + #[inline(always)] + fn unexpected_eof() -> Box<::ErrorKind> { + Box::new(::ErrorKind::Io(io::Error::new( + io::ErrorKind::UnexpectedEof, + "", + ))) + } +} + +impl<'storage> BincodeRead<'storage> for SliceReader<'storage> { + #[inline(always)] + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + use ErrorKind; + let string = match ::std::str::from_utf8(self.get_byte_slice(length)?) { + Ok(s) => s, + Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()), + }; + visitor.visit_borrowed_str(string) + } + + #[inline(always)] + fn get_byte_buffer(&mut self, length: usize) -> Result> { + self.get_byte_slice(length).map(|x| x.to_vec()) + } + + #[inline(always)] + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + visitor.visit_borrowed_bytes(self.get_byte_slice(length)?) + } +} + +impl IoReader +where + R: io::Read, +{ + fn fill_buffer(&mut self, length: usize) -> Result<()> { + self.temp_buffer.resize(length, 0); + + self.reader.read_exact(&mut self.temp_buffer)?; + + Ok(()) + } +} + +impl<'a, R> BincodeRead<'a> for IoReader +where + R: io::Read, +{ + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'a>, + { + self.fill_buffer(length)?; + + let string = match ::std::str::from_utf8(&self.temp_buffer[..]) { + Ok(s) => s, + Err(e) => return Err(::ErrorKind::InvalidUtf8Encoding(e).into()), + }; + + visitor.visit_str(string) + } + + fn get_byte_buffer(&mut self, length: usize) -> Result> { + self.fill_buffer(length)?; + Ok(::std::mem::replace(&mut self.temp_buffer, Vec::new())) + } + + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'a>, + { + self.fill_buffer(length)?; + visitor.visit_bytes(&self.temp_buffer[..]) + } +} + +#[cfg(test)] +mod test { + use super::IoReader; + + #[test] + fn test_fill_buffer() { + let buffer = vec![0u8; 64]; + let mut reader = IoReader::new(buffer.as_slice()); + + reader.fill_buffer(20).unwrap(); + assert_eq!(20, reader.temp_buffer.len()); + + reader.fill_buffer(30).unwrap(); + assert_eq!(30, reader.temp_buffer.len()); + + reader.fill_buffer(5).unwrap(); + assert_eq!(5, reader.temp_buffer.len()); + } +} diff --git a/vendor/bincode/src/error.rs b/vendor/bincode/src/error.rs new file mode 100644 index 000000000..420fa7ab7 --- /dev/null +++ b/vendor/bincode/src/error.rs @@ -0,0 +1,115 @@ +use std::error::Error as StdError; +use std::io; +use std::str::Utf8Error; +use std::{error, fmt}; + +use serde; + +/// The result of a serialization or deserialization operation. +pub type Result = ::std::result::Result; + +/// An error that can be produced during (de)serializing. +pub type Error = Box; + +/// The kind of error that can be produced during a serialization or deserialization. +#[derive(Debug)] +pub enum ErrorKind { + /// If the error stems from the reader/writer that is being used + /// during (de)serialization, that error will be stored and returned here. + Io(io::Error), + /// Returned if the deserializer attempts to deserialize a string that is not valid utf8 + InvalidUtf8Encoding(Utf8Error), + /// Returned if the deserializer attempts to deserialize a bool that was + /// not encoded as either a 1 or a 0 + InvalidBoolEncoding(u8), + /// Returned if the deserializer attempts to deserialize a char that is not in the correct format. + InvalidCharEncoding, + /// Returned if the deserializer attempts to deserialize the tag of an enum that is + /// not in the expected ranges + InvalidTagEncoding(usize), + /// Serde has a deserialize_any method that lets the format hint to the + /// object which route to take in deserializing. + DeserializeAnyNotSupported, + /// If (de)serializing a message takes more than the provided size limit, this + /// error is returned. + SizeLimit, + /// Bincode can not encode sequences of unknown length (like iterators). + SequenceMustHaveLength, + /// A custom error message from Serde. + Custom(String), +} + +impl StdError for ErrorKind { + fn description(&self) -> &str { + match *self { + ErrorKind::Io(ref err) => error::Error::description(err), + ErrorKind::InvalidUtf8Encoding(_) => "string is not valid utf8", + ErrorKind::InvalidBoolEncoding(_) => "invalid u8 while decoding bool", + ErrorKind::InvalidCharEncoding => "char is not valid", + ErrorKind::InvalidTagEncoding(_) => "tag for enum is not valid", + ErrorKind::SequenceMustHaveLength => { + "Bincode can only encode sequences and maps that have a knowable size ahead of time" + } + ErrorKind::DeserializeAnyNotSupported => { + "Bincode doesn't support serde::Deserializer::deserialize_any" + } + ErrorKind::SizeLimit => "the size limit has been reached", + ErrorKind::Custom(ref msg) => msg, + } + } + + fn cause(&self) -> Option<&error::Error> { + match *self { + ErrorKind::Io(ref err) => Some(err), + ErrorKind::InvalidUtf8Encoding(_) => None, + ErrorKind::InvalidBoolEncoding(_) => None, + ErrorKind::InvalidCharEncoding => None, + ErrorKind::InvalidTagEncoding(_) => None, + ErrorKind::SequenceMustHaveLength => None, + ErrorKind::DeserializeAnyNotSupported => None, + ErrorKind::SizeLimit => None, + ErrorKind::Custom(_) => None, + } + } +} + +impl From for Error { + fn from(err: io::Error) -> Error { + ErrorKind::Io(err).into() + } +} + +impl fmt::Display for ErrorKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + ErrorKind::Io(ref ioerr) => write!(fmt, "io error: {}", ioerr), + ErrorKind::InvalidUtf8Encoding(ref e) => write!(fmt, "{}: {}", self.description(), e), + ErrorKind::InvalidBoolEncoding(b) => { + write!(fmt, "{}, expected 0 or 1, found {}", self.description(), b) + } + ErrorKind::InvalidCharEncoding => write!(fmt, "{}", self.description()), + ErrorKind::InvalidTagEncoding(tag) => { + write!(fmt, "{}, found {}", self.description(), tag) + } + ErrorKind::SequenceMustHaveLength => write!(fmt, "{}", self.description()), + ErrorKind::SizeLimit => write!(fmt, "{}", self.description()), + ErrorKind::DeserializeAnyNotSupported => write!( + fmt, + "Bincode does not support the serde::Deserializer::deserialize_any method" + ), + ErrorKind::Custom(ref s) => s.fmt(fmt), + } + } +} + +impl serde::de::Error for Error { + fn custom(desc: T) -> Error { + ErrorKind::Custom(desc.to_string()).into() + } +} + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self { + ErrorKind::Custom(msg.to_string()).into() + } +} diff --git a/vendor/bincode/src/internal.rs b/vendor/bincode/src/internal.rs new file mode 100644 index 000000000..1d2a9a129 --- /dev/null +++ b/vendor/bincode/src/internal.rs @@ -0,0 +1,124 @@ +use serde; +use std::io::{Read, Write}; +use std::marker::PhantomData; + +use config::{Infinite, InternalOptions, Options, SizeLimit, TrailingBytes}; +use de::read::BincodeRead; +use Result; + +pub(crate) fn serialize_into(writer: W, value: &T, mut options: O) -> Result<()> +where + W: Write, + T: serde::Serialize, + O: InternalOptions, +{ + if options.limit().limit().is_some() { + // "compute" the size for the side-effect + // of returning Err if the bound was reached. + serialized_size(value, &mut options)?; + } + + let mut serializer = ::ser::Serializer::<_, O>::new(writer, options); + serde::Serialize::serialize(value, &mut serializer) +} + +pub(crate) fn serialize(value: &T, mut options: O) -> Result> +where + T: serde::Serialize, + O: InternalOptions, +{ + let mut writer = { + let actual_size = serialized_size(value, &mut options)?; + Vec::with_capacity(actual_size as usize) + }; + + serialize_into(&mut writer, value, options.with_no_limit())?; + Ok(writer) +} + +pub(crate) fn serialized_size(value: &T, options: O) -> Result +where + T: serde::Serialize, +{ + let mut size_counter = ::ser::SizeChecker { options, total: 0 }; + + let result = value.serialize(&mut size_counter); + result.map(|_| size_counter.total) +} + +pub(crate) fn deserialize_from(reader: R, options: O) -> Result +where + R: Read, + T: serde::de::DeserializeOwned, + O: InternalOptions, +{ + deserialize_from_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_seed<'a, R, T, O>(seed: T, reader: R, options: O) -> Result +where + R: Read, + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let reader = ::de::read::IoReader::new(reader); + deserialize_from_custom_seed(seed, reader, options) +} + +pub(crate) fn deserialize_from_custom<'a, R, T, O>(reader: R, options: O) -> Result +where + R: BincodeRead<'a>, + T: serde::de::DeserializeOwned, + O: InternalOptions, +{ + deserialize_from_custom_seed(PhantomData, reader, options) +} + +pub(crate) fn deserialize_from_custom_seed<'a, R, T, O>( + seed: T, + reader: R, + options: O, +) -> Result +where + R: BincodeRead<'a>, + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let mut deserializer = ::de::Deserializer::<_, O>::with_bincode_read(reader, options); + seed.deserialize(&mut deserializer) +} + +pub(crate) fn deserialize_in_place<'a, R, T, O>(reader: R, options: O, place: &mut T) -> Result<()> +where + R: BincodeRead<'a>, + T: serde::de::Deserialize<'a>, + O: InternalOptions, +{ + let mut deserializer = ::de::Deserializer::<_, _>::with_bincode_read(reader, options); + serde::Deserialize::deserialize_in_place(&mut deserializer, place) +} + +pub(crate) fn deserialize<'a, T, O>(bytes: &'a [u8], options: O) -> Result +where + T: serde::de::Deserialize<'a>, + O: InternalOptions, +{ + deserialize_seed(PhantomData, bytes, options) +} + +pub(crate) fn deserialize_seed<'a, T, O>(seed: T, bytes: &'a [u8], options: O) -> Result +where + T: serde::de::DeserializeSeed<'a>, + O: InternalOptions, +{ + let options = ::config::WithOtherLimit::new(options, Infinite); + + let reader = ::de::read::SliceReader::new(bytes); + let mut deserializer = ::de::Deserializer::with_bincode_read(reader, options); + let val = seed.deserialize(&mut deserializer)?; + + match O::Trailing::check_end(&deserializer.reader) { + Ok(_) => Ok(val), + Err(err) => Err(err), + } +} diff --git a/vendor/bincode/src/lib.rs b/vendor/bincode/src/lib.rs new file mode 100644 index 000000000..3969ab773 --- /dev/null +++ b/vendor/bincode/src/lib.rs @@ -0,0 +1,201 @@ +#![deny(missing_docs)] +#![allow(unknown_lints, bare_trait_objects, deprecated)] + +//! Bincode is a crate for encoding and decoding using a tiny binary +//! serialization strategy. Using it, you can easily go from having +//! an object in memory, quickly serialize it to bytes, and then +//! deserialize it back just as fast! +//! +//! ### Using Basic Functions +//! +//! ```edition2018 +//! fn main() { +//! // The object that we will serialize. +//! let target: Option = Some("hello world".to_string()); +//! +//! let encoded: Vec = bincode::serialize(&target).unwrap(); +//! let decoded: Option = bincode::deserialize(&encoded[..]).unwrap(); +//! assert_eq!(target, decoded); +//! } +//! ``` +//! +//! ### 128bit numbers +//! +//! Support for `i128` and `u128` is automatically enabled on Rust toolchains +//! greater than or equal to `1.26.0` and disabled for targets which do not support it + +#![doc(html_root_url = "https://docs.rs/bincode/1.3.3")] +#![crate_name = "bincode"] +#![crate_type = "rlib"] +#![crate_type = "dylib"] + +#[macro_use] +extern crate serde; + +pub mod config; +/// Deserialize bincode data to a Rust data structure. +pub mod de; + +mod byteorder; +mod error; +mod internal; +mod ser; + +pub use config::{Config, DefaultOptions, Options}; +pub use de::read::BincodeRead; +pub use de::Deserializer; +pub use error::{Error, ErrorKind, Result}; +pub use ser::Serializer; + +/// Get a default configuration object. +/// +/// ### Default Configuration: +/// +/// | Byte limit | Endianness | +/// |------------|------------| +/// | Unlimited | Little | +#[inline(always)] +#[deprecated(since = "1.3.0", note = "please use `options()` instead")] +pub fn config() -> Config { + Config::new() +} + +/// Get a default configuration object. +/// +/// **Warning:** the default configuration returned by this function +/// is not the same as that used by the other functions in this +/// module. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +/// +/// ### Default Configuration: +/// +/// | Byte limit | Endianness | Int Encoding | Trailing Behavior | +/// |------------|------------|--------------|-------------------| +/// | Unlimited | Little | Varint | Reject | +#[inline(always)] +pub fn options() -> DefaultOptions { + DefaultOptions::new() +} + +/// Serializes an object directly into a `Writer` using the default configuration. +/// +/// If the serialization would take more bytes than allowed by the size limit, an error +/// is returned and *no bytes* will be written into the `Writer`. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialize_into(writer: W, value: &T) -> Result<()> +where + W: std::io::Write, + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .serialize_into(writer, value) +} + +/// Serializes a serializable object into a `Vec` of bytes using the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialize(value: &T) -> Result> +where + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialize(value) +} + +/// Deserializes an object directly from a `Read`er using the default configuration. +/// +/// If this returns an `Error`, `reader` may be in an invalid state. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize_from(reader: R) -> Result +where + R: std::io::Read, + T: serde::de::DeserializeOwned, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_from(reader) +} + +/// Deserializes an object from a custom `BincodeRead`er using the default configuration. +/// It is highly recommended to use `deserialize_from` unless you need to implement +/// `BincodeRead` for performance reasons. +/// +/// If this returns an `Error`, `reader` may be in an invalid state. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize_from_custom<'a, R, T>(reader: R) -> Result +where + R: de::read::BincodeRead<'a>, + T: serde::de::DeserializeOwned, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_from_custom(reader) +} + +/// Only use this if you know what you're doing. +/// +/// This is part of the public API. +#[doc(hidden)] +pub fn deserialize_in_place<'a, R, T>(reader: R, place: &mut T) -> Result<()> +where + T: serde::de::Deserialize<'a>, + R: BincodeRead<'a>, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_in_place(reader, place) +} + +/// Deserializes a slice of bytes into an instance of `T` using the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result +where + T: serde::de::Deserialize<'a>, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize(bytes) +} + +/// Returns the size that an object would be if serialized using Bincode with the default configuration. +/// +/// **Warning:** the default configuration used by this function is not +/// the same as that used by the `DefaultOptions` struct. See the +/// [config](config/index.html#options-struct-vs-bincode-functions) +/// module for more details +pub fn serialized_size(value: &T) -> Result +where + T: serde::Serialize, +{ + DefaultOptions::new() + .with_fixint_encoding() + .allow_trailing_bytes() + .serialized_size(value) +} diff --git a/vendor/bincode/src/ser/mod.rs b/vendor/bincode/src/ser/mod.rs new file mode 100644 index 000000000..be4f3f223 --- /dev/null +++ b/vendor/bincode/src/ser/mod.rs @@ -0,0 +1,772 @@ +use std::io::Write; +use std::u32; + +use serde; + +use byteorder::WriteBytesExt; + +use super::config::{IntEncoding, SizeLimit}; +use super::{Error, ErrorKind, Result}; +use config::{BincodeByteOrder, Options}; +use std::mem::size_of; + +/// An Serializer that encodes values directly into a Writer. +/// +/// The specified byte-order will impact the endianness that is +/// used during the encoding. +/// +/// This struct should not be used often. +/// For most cases, prefer the `encode_into` function. +pub struct Serializer { + writer: W, + _options: O, +} + +macro_rules! impl_serialize_literal { + ($ser_method:ident($ty:ty) = $write:ident()) => { + pub(crate) fn $ser_method(&mut self, v: $ty) -> Result<()> { + self.writer + .$write::<::Endian>(v) + .map_err(Into::into) + } + }; +} + +impl Serializer { + /// Creates a new Serializer with the given `Write`r. + pub fn new(w: W, options: O) -> Serializer { + Serializer { + writer: w, + _options: options, + } + } + + pub(crate) fn serialize_byte(&mut self, v: u8) -> Result<()> { + self.writer.write_u8(v).map_err(Into::into) + } + + impl_serialize_literal! {serialize_literal_u16(u16) = write_u16()} + impl_serialize_literal! {serialize_literal_u32(u32) = write_u32()} + impl_serialize_literal! {serialize_literal_u64(u64) = write_u64()} + + serde_if_integer128! { + impl_serialize_literal!{serialize_literal_u128(u128) = write_u128()} + } +} + +macro_rules! impl_serialize_int { + ($ser_method:ident($ty:ty) = $ser_int:ident()) => { + fn $ser_method(self, v: $ty) -> Result<()> { + O::IntEncoding::$ser_int(self, v) + } + }; +} + +impl<'a, W: Write, O: Options> serde::Serializer for &'a mut Serializer { + type Ok = (); + type Error = Error; + type SerializeSeq = Compound<'a, W, O>; + type SerializeTuple = Compound<'a, W, O>; + type SerializeTupleStruct = Compound<'a, W, O>; + type SerializeTupleVariant = Compound<'a, W, O>; + type SerializeMap = Compound<'a, W, O>; + type SerializeStruct = Compound<'a, W, O>; + type SerializeStructVariant = Compound<'a, W, O>; + + fn serialize_unit(self) -> Result<()> { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { + Ok(()) + } + + fn serialize_bool(self, v: bool) -> Result<()> { + self.serialize_byte(v as u8) + } + + fn serialize_u8(self, v: u8) -> Result<()> { + self.serialize_byte(v) + } + + impl_serialize_int! {serialize_u16(u16) = serialize_u16()} + impl_serialize_int! {serialize_u32(u32) = serialize_u32()} + impl_serialize_int! {serialize_u64(u64) = serialize_u64()} + + fn serialize_i8(self, v: i8) -> Result<()> { + self.serialize_byte(v as u8) + } + + impl_serialize_int! {serialize_i16(i16) = serialize_i16()} + impl_serialize_int! {serialize_i32(i32) = serialize_i32()} + impl_serialize_int! {serialize_i64(i64) = serialize_i64()} + + serde_if_integer128! { + impl_serialize_int!{serialize_u128(u128) = serialize_u128()} + impl_serialize_int!{serialize_i128(i128) = serialize_i128()} + } + + fn serialize_f32(self, v: f32) -> Result<()> { + self.writer + .write_f32::<::Endian>(v) + .map_err(Into::into) + } + + fn serialize_f64(self, v: f64) -> Result<()> { + self.writer + .write_f64::<::Endian>(v) + .map_err(Into::into) + } + + fn serialize_str(self, v: &str) -> Result<()> { + O::IntEncoding::serialize_len(self, v.len())?; + self.writer.write_all(v.as_bytes()).map_err(Into::into) + } + + fn serialize_char(self, c: char) -> Result<()> { + self.writer + .write_all(encode_utf8(c).as_slice()) + .map_err(Into::into) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + O::IntEncoding::serialize_len(self, v.len())?; + self.writer.write_all(v).map_err(Into::into) + } + + fn serialize_none(self) -> Result<()> { + self.writer.write_u8(0).map_err(Into::into) + } + + fn serialize_some(self, v: &T) -> Result<()> + where + T: serde::Serialize, + { + self.writer.write_u8(1)?; + v.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + O::IntEncoding::serialize_len(self, len)?; + Ok(Compound { ser: self }) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + O::IntEncoding::serialize_u32(self, variant_index)?; + Ok(Compound { ser: self }) + } + + fn serialize_map(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + O::IntEncoding::serialize_len(self, len)?; + Ok(Compound { ser: self }) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(Compound { ser: self }) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + O::IntEncoding::serialize_u32(self, variant_index)?; + Ok(Compound { ser: self }) + } + + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + value: &T, + ) -> Result<()> + where + T: serde::ser::Serialize, + { + O::IntEncoding::serialize_u32(self, variant_index)?; + value.serialize(self) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + O::IntEncoding::serialize_u32(self, variant_index) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +pub(crate) struct SizeChecker { + pub options: O, + pub total: u64, +} + +impl SizeChecker { + fn add_raw(&mut self, size: u64) -> Result<()> { + self.options.limit().add(size)?; + self.total += size; + + Ok(()) + } + + fn add_discriminant(&mut self, idx: u32) -> Result<()> { + let bytes = O::IntEncoding::u32_size(idx); + self.add_raw(bytes) + } + + fn add_len(&mut self, len: usize) -> Result<()> { + let bytes = O::IntEncoding::len_size(len); + self.add_raw(bytes) + } +} + +macro_rules! impl_size_int { + ($ser_method:ident($ty:ty) = $size_method:ident()) => { + fn $ser_method(self, v: $ty) -> Result<()> { + self.add_raw(O::IntEncoding::$size_method(v)) + } + }; +} + +impl<'a, O: Options> serde::Serializer for &'a mut SizeChecker { + type Ok = (); + type Error = Error; + type SerializeSeq = SizeCompound<'a, O>; + type SerializeTuple = SizeCompound<'a, O>; + type SerializeTupleStruct = SizeCompound<'a, O>; + type SerializeTupleVariant = SizeCompound<'a, O>; + type SerializeMap = SizeCompound<'a, O>; + type SerializeStruct = SizeCompound<'a, O>; + type SerializeStructVariant = SizeCompound<'a, O>; + + fn serialize_unit(self) -> Result<()> { + Ok(()) + } + + fn serialize_unit_struct(self, _: &'static str) -> Result<()> { + Ok(()) + } + + fn serialize_bool(self, _: bool) -> Result<()> { + self.add_raw(1) + } + + fn serialize_u8(self, _: u8) -> Result<()> { + self.add_raw(1) + } + fn serialize_i8(self, _: i8) -> Result<()> { + self.add_raw(1) + } + + impl_size_int! {serialize_u16(u16) = u16_size()} + impl_size_int! {serialize_u32(u32) = u32_size()} + impl_size_int! {serialize_u64(u64) = u64_size()} + impl_size_int! {serialize_i16(i16) = i16_size()} + impl_size_int! {serialize_i32(i32) = i32_size()} + impl_size_int! {serialize_i64(i64) = i64_size()} + + serde_if_integer128! { + impl_size_int!{serialize_u128(u128) = u128_size()} + impl_size_int!{serialize_i128(i128) = i128_size()} + } + + fn serialize_f32(self, _: f32) -> Result<()> { + self.add_raw(size_of::() as u64) + } + + fn serialize_f64(self, _: f64) -> Result<()> { + self.add_raw(size_of::() as u64) + } + + fn serialize_str(self, v: &str) -> Result<()> { + self.add_len(v.len())?; + self.add_raw(v.len() as u64) + } + + fn serialize_char(self, c: char) -> Result<()> { + self.add_raw(encode_utf8(c).as_slice().len() as u64) + } + + fn serialize_bytes(self, v: &[u8]) -> Result<()> { + self.add_len(v.len())?; + self.add_raw(v.len() as u64) + } + + fn serialize_none(self) -> Result<()> { + self.add_raw(1) + } + + fn serialize_some(self, v: &T) -> Result<()> + where + T: serde::Serialize, + { + self.add_raw(1)?; + v.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + + self.add_len(len)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + self.add_raw(O::IntEncoding::u32_size(variant_index))?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_map(self, len: Option) -> Result { + let len = len.ok_or(ErrorKind::SequenceMustHaveLength)?; + + self.add_len(len)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Ok(SizeCompound { ser: self }) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + self.add_discriminant(variant_index)?; + Ok(SizeCompound { ser: self }) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + v: &V, + ) -> Result<()> { + v.serialize(self) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + ) -> Result<()> { + self.add_discriminant(variant_index) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + variant_index: u32, + _variant: &'static str, + value: &V, + ) -> Result<()> { + self.add_discriminant(variant_index)?; + value.serialize(self) + } + + fn is_human_readable(&self) -> bool { + false + } +} + +pub struct Compound<'a, W: 'a, O: Options + 'a> { + ser: &'a mut Serializer, +} + +impl<'a, W, O> serde::ser::SerializeSeq for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTuple for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTupleStruct for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeTupleVariant for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeMap for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where + K: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where + V: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeStruct for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, W, O> serde::ser::SerializeStructVariant for Compound<'a, W, O> +where + W: Write, + O: Options, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +pub(crate) struct SizeCompound<'a, S: Options + 'a> { + ser: &'a mut SizeChecker, +} + +impl<'a, O: Options> serde::ser::SerializeSeq for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTuple for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTupleStruct for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeTupleVariant for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options + 'a> serde::ser::SerializeMap for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, value: &K) -> Result<()> + where + K: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn serialize_value(&mut self, value: &V) -> Result<()> + where + V: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeStruct for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} + +impl<'a, O: Options> serde::ser::SerializeStructVariant for SizeCompound<'a, O> { + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, _key: &'static str, value: &T) -> Result<()> + where + T: serde::ser::Serialize, + { + value.serialize(&mut *self.ser) + } + + #[inline] + fn end(self) -> Result<()> { + Ok(()) + } +} +const TAG_CONT: u8 = 0b1000_0000; +const TAG_TWO_B: u8 = 0b1100_0000; +const TAG_THREE_B: u8 = 0b1110_0000; +const TAG_FOUR_B: u8 = 0b1111_0000; +const MAX_ONE_B: u32 = 0x80; +const MAX_TWO_B: u32 = 0x800; +const MAX_THREE_B: u32 = 0x10000; + +fn encode_utf8(c: char) -> EncodeUtf8 { + let code = c as u32; + let mut buf = [0; 4]; + let pos = if code < MAX_ONE_B { + buf[3] = code as u8; + 3 + } else if code < MAX_TWO_B { + buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 2 + } else if code < MAX_THREE_B { + buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 1 + } else { + buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; + buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; + buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; + buf[3] = (code & 0x3F) as u8 | TAG_CONT; + 0 + }; + EncodeUtf8 { buf, pos } +} + +struct EncodeUtf8 { + buf: [u8; 4], + pos: usize, +} + +impl EncodeUtf8 { + fn as_slice(&self) -> &[u8] { + &self.buf[self.pos..] + } +} diff --git a/vendor/bincode/tests/test.rs b/vendor/bincode/tests/test.rs new file mode 100644 index 000000000..23d65f48a --- /dev/null +++ b/vendor/bincode/tests/test.rs @@ -0,0 +1,899 @@ +#[macro_use] +extern crate serde_derive; + +extern crate bincode; +#[macro_use] +extern crate serde; +extern crate serde_bytes; + +use std::borrow::Cow; +use std::collections::HashMap; +use std::fmt::{self, Debug}; +use std::result::Result as StdResult; + +use bincode::{ + deserialize, deserialize_from, deserialize_in_place, serialize, serialized_size, + DefaultOptions, ErrorKind, Options, Result, +}; +use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor}; + +const LEN_SIZE: u64 = 8; + +fn the_same_impl(element: V, options: &mut O) +where + V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + 'static, + O: Options, +{ + let size = options.serialized_size(&element).unwrap(); + + { + let encoded = options.serialize(&element).unwrap(); + let decoded: V = options.deserialize(&encoded[..]).unwrap(); + let decoded_reader = options.deserialize_from(&mut &encoded[..]).unwrap(); + + assert_eq!(element, decoded); + assert_eq!(element, decoded_reader); + assert_eq!(size, encoded.len() as u64); + } +} + +fn the_same(element: V) +where + V: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug + Clone + 'static, +{ + // add a new macro which calls the previous when you add a new option set + macro_rules! all_endians { + ($element:expr, $options:expr) => { + the_same_impl($element.clone(), &mut $options.with_native_endian()); + the_same_impl($element.clone(), &mut $options.with_big_endian()); + the_same_impl($element.clone(), &mut $options.with_little_endian()); + }; + } + + macro_rules! all_integer_encodings { + ($element:expr, $options:expr) => { + all_endians!($element, $options.with_fixint_encoding()); + all_endians!($element, $options.with_varint_encoding()); + }; + } + + all_integer_encodings!(element, DefaultOptions::new()); +} + +#[test] +fn test_numbers() { + // unsigned positive + the_same(5u8); + the_same(5u16); + the_same(5u32); + the_same(5u64); + the_same(5usize); + // signed positive + the_same(5i8); + the_same(5i16); + the_same(5i32); + the_same(5i64); + the_same(5isize); + // signed negative + the_same(-5i8); + the_same(-5i16); + the_same(-5i32); + the_same(-5i64); + the_same(-5isize); + // floating + the_same(-100f32); + the_same(0f32); + the_same(5f32); + the_same(-100f64); + the_same(5f64); +} + +serde_if_integer128! { + #[test] + fn test_numbers_128bit() { + // unsigned positive + the_same(5u128); + the_same(u128::max_value()); + // signed positive + the_same(5i128); + the_same(i128::max_value()); + // signed negative + the_same(-5i128); + the_same(i128::min_value()); + } +} + +#[test] +fn test_string() { + the_same("".to_string()); + the_same("a".to_string()); +} + +#[test] +fn test_tuple() { + the_same((1isize,)); + the_same((1isize, 2isize, 3isize)); + the_same((1isize, "foo".to_string(), ())); +} + +#[test] +fn test_basic_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Easy { + x: isize, + s: String, + y: usize, + } + the_same(Easy { + x: -4, + s: "foo".to_string(), + y: 10, + }); +} + +#[test] +fn test_nested_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Easy { + x: isize, + s: String, + y: usize, + } + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Nest { + f: Easy, + b: usize, + s: Easy, + } + + the_same(Nest { + f: Easy { + x: -1, + s: "foo".to_string(), + y: 20, + }, + b: 100, + s: Easy { + x: -100, + s: "bar".to_string(), + y: 20, + }, + }); +} + +#[test] +fn test_struct_newtype() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct NewtypeStr(usize); + + the_same(NewtypeStr(5)); +} + +#[test] +fn test_struct_tuple() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct TubStr(usize, String, f32); + + the_same(TubStr(5, "hello".to_string(), 3.2)); +} + +#[test] +fn test_option() { + the_same(Some(5usize)); + the_same(Some("foo bar".to_string())); + the_same(None::); +} + +#[test] +fn test_enum() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + enum TestEnum { + NoArg, + OneArg(usize), + Args(usize, usize), + AnotherNoArg, + StructLike { x: usize, y: f32 }, + } + the_same(TestEnum::NoArg); + the_same(TestEnum::OneArg(4)); + //the_same(TestEnum::Args(4, 5)); + the_same(TestEnum::AnotherNoArg); + the_same(TestEnum::StructLike { x: 4, y: 3.14159 }); + the_same(vec![ + TestEnum::NoArg, + TestEnum::OneArg(5), + TestEnum::AnotherNoArg, + TestEnum::StructLike { x: 4, y: 1.4 }, + ]); +} + +#[test] +fn test_vec() { + let v: Vec = vec![]; + the_same(v); + the_same(vec![1u64]); + the_same(vec![1u64, 2, 3, 4, 5, 6]); +} + +#[test] +fn test_map() { + let mut m = HashMap::new(); + m.insert(4u64, "foo".to_string()); + m.insert(0u64, "bar".to_string()); + the_same(m); +} + +#[test] +fn test_bool() { + the_same(true); + the_same(false); +} + +#[test] +fn test_unicode() { + the_same("å".to_string()); + the_same("aåååååååa".to_string()); +} + +#[test] +fn test_fixed_size_array() { + the_same([24u32; 32]); + the_same([1u64, 2, 3, 4, 5, 6, 7, 8]); + the_same([0u8; 19]); +} + +#[test] +fn deserializing_errors() { + match *deserialize::(&vec![0xA][..]).unwrap_err() { + ErrorKind::InvalidBoolEncoding(0xA) => {} + _ => panic!(), + } + + let invalid_str = vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF]; + + match *deserialize::(&invalid_str[..]).unwrap_err() { + ErrorKind::InvalidUtf8Encoding(_) => {} + _ => panic!(), + } + + // Out-of-bounds variant + #[derive(Serialize, Deserialize, Debug)] + enum Test { + One, + Two, + }; + + let invalid_enum = vec![0, 0, 0, 5]; + + match *deserialize::(&invalid_enum[..]).unwrap_err() { + // Error message comes from serde + ErrorKind::Custom(_) => {} + _ => panic!(), + } + match *deserialize::>(&vec![5, 0][..]).unwrap_err() { + ErrorKind::InvalidTagEncoding(_) => {} + _ => panic!(), + } +} + +#[test] +fn trailing_bytes() { + match DefaultOptions::new() + .deserialize::(b"1x") + .map_err(|e| *e) + { + Err(ErrorKind::Custom(_)) => {} + other => panic!("Expecting TrailingBytes, got {:?}", other), + } +} + +#[test] +fn too_big_deserialize() { + let serialized = vec![0, 0, 0, 3]; + let deserialized: Result = DefaultOptions::new() + .with_fixint_encoding() + .with_limit(3) + .deserialize_from(&mut &serialized[..]); + assert!(deserialized.is_err()); + + let serialized = vec![0, 0, 0, 3]; + let deserialized: Result = DefaultOptions::new() + .with_fixint_encoding() + .with_limit(4) + .deserialize_from(&mut &serialized[..]); + assert!(deserialized.is_ok()); +} + +#[test] +fn char_serialization() { + let chars = "Aa\0☺♪"; + for c in chars.chars() { + let encoded = DefaultOptions::new() + .with_limit(4) + .serialize(&c) + .expect("serializing char failed"); + let decoded: char = deserialize(&encoded).expect("deserializing failed"); + assert_eq!(decoded, c); + } +} + +#[test] +fn too_big_char_deserialize() { + let serialized = vec![0x41]; + let deserialized: Result = DefaultOptions::new() + .with_limit(1) + .deserialize_from(&mut &serialized[..]); + assert!(deserialized.is_ok()); + assert_eq!(deserialized.unwrap(), 'A'); +} + +#[test] +fn too_big_serialize() { + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(3) + .serialize(&0u32) + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(4) + .serialize(&0u32) + .is_ok()); + + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(LEN_SIZE + 4) + .serialize(&"abcde") + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(LEN_SIZE + 5) + .serialize(&"abcde") + .is_ok()); +} + +#[test] +fn test_serialized_size() { + assert!(serialized_size(&0u8).unwrap() == 1); + assert!(serialized_size(&0u16).unwrap() == 2); + assert!(serialized_size(&0u32).unwrap() == 4); + assert!(serialized_size(&0u64).unwrap() == 8); + + // length isize stored as u64 + assert!(serialized_size(&"").unwrap() == LEN_SIZE); + assert!(serialized_size(&"a").unwrap() == LEN_SIZE + 1); + + assert!(serialized_size(&vec![0u32, 1u32, 2u32]).unwrap() == LEN_SIZE + 3 * (4)); +} + +#[test] +fn test_serialized_size_bounded() { + // JUST RIGHT + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(1) + .serialized_size(&0u8) + .unwrap() + == 1 + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(2) + .serialized_size(&0u16) + .unwrap() + == 2 + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(4) + .serialized_size(&0u32) + .unwrap() + == 4 + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(8) + .serialized_size(&0u64) + .unwrap() + == 8 + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(8) + .serialized_size(&"") + .unwrap() + == LEN_SIZE + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(8 + 1) + .serialized_size(&"a") + .unwrap() + == LEN_SIZE + 1 + ); + assert!( + DefaultOptions::new() + .with_fixint_encoding() + .with_limit(LEN_SIZE + 3 * 4) + .serialized_size(&vec![0u32, 1u32, 2u32]) + .unwrap() + == LEN_SIZE + 3 * 4 + ); + // Below + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(0) + .serialized_size(&0u8) + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(1) + .serialized_size(&0u16) + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(3) + .serialized_size(&0u32) + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(7) + .serialized_size(&0u64) + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(7) + .serialized_size(&"") + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(8 + 0) + .serialized_size(&"a") + .is_err()); + assert!(DefaultOptions::new() + .with_fixint_encoding() + .with_limit(8 + 3 * 4 - 1) + .serialized_size(&vec![0u32, 1u32, 2u32]) + .is_err()); +} + +#[test] +fn encode_box() { + the_same(Box::new(5)); +} + +#[test] +fn test_cow_serialize() { + let large_object = vec![1u32, 2, 3, 4, 5, 6]; + let mut large_map = HashMap::new(); + large_map.insert(1, 2); + + #[derive(Serialize, Deserialize, Debug)] + enum Message<'a> { + M1(Cow<'a, Vec>), + M2(Cow<'a, HashMap>), + } + + // Test 1 + { + let serialized = serialize(&Message::M1(Cow::Borrowed(&large_object))).unwrap(); + let deserialized: Message<'static> = deserialize_from(&mut &serialized[..]).unwrap(); + + match deserialized { + Message::M1(b) => assert!(&b.into_owned() == &large_object), + _ => assert!(false), + } + } + + // Test 2 + { + let serialized = serialize(&Message::M2(Cow::Borrowed(&large_map))).unwrap(); + let deserialized: Message<'static> = deserialize_from(&mut &serialized[..]).unwrap(); + + match deserialized { + Message::M2(b) => assert!(&b.into_owned() == &large_map), + _ => assert!(false), + } + } +} + +#[test] +fn test_strbox_serialize() { + let strx: &'static str = "hello world"; + let serialized = serialize(&Cow::Borrowed(strx)).unwrap(); + let deserialized: Cow<'static, String> = deserialize_from(&mut &serialized[..]).unwrap(); + let stringx: String = deserialized.into_owned(); + assert!(strx == &stringx[..]); +} + +#[test] +fn test_slicebox_serialize() { + let slice = [1u32, 2, 3, 4, 5]; + let serialized = serialize(&Cow::Borrowed(&slice[..])).unwrap(); + println!("{:?}", serialized); + let deserialized: Cow<'static, Vec> = deserialize_from(&mut &serialized[..]).unwrap(); + { + let sb: &[u32] = &deserialized; + assert!(slice == sb); + } + let vecx: Vec = deserialized.into_owned(); + assert!(slice == &vecx[..]); +} + +#[test] +fn test_multi_strings_serialize() { + assert!(serialize(&("foo", "bar", "baz")).is_ok()); +} + +#[test] +fn test_oom_protection() { + use std::io::Cursor; + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct FakeVec { + len: u64, + byte: u8, + } + let x = DefaultOptions::new() + .with_limit(10) + .serialize(&FakeVec { + len: 0xffffffffffffffffu64, + byte: 1, + }) + .unwrap(); + let y: Result> = DefaultOptions::new() + .with_limit(10) + .deserialize_from(&mut Cursor::new(&x[..])); + assert!(y.is_err()); +} + +#[test] +fn path_buf() { + use std::path::{Path, PathBuf}; + let path = Path::new("foo").to_path_buf(); + let serde_encoded = serialize(&path).unwrap(); + let decoded: PathBuf = deserialize(&serde_encoded).unwrap(); + assert!(path.to_str() == decoded.to_str()); +} + +#[test] +fn bytes() { + use serde_bytes::Bytes; + + let data = b"abc\0123"; + let s = serialize(&data[..]).unwrap(); + let s2 = serialize(&Bytes::new(data)).unwrap(); + assert_eq!(s[..], s2[..]); +} + +#[test] +fn serde_bytes() { + use serde_bytes::ByteBuf; + the_same(ByteBuf::from(vec![1, 2, 3, 4, 5])); +} + +#[test] +fn endian_difference() { + let x = 10u64; + let little = serialize(&x).unwrap(); + let big = DefaultOptions::new() + .with_big_endian() + .serialize(&x) + .unwrap(); + assert_ne!(little, big); +} + +#[test] +fn test_zero_copy_parse() { + #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] + struct Foo<'a> { + borrowed_str: &'a str, + borrowed_bytes: &'a [u8], + } + + let f = Foo { + borrowed_str: "hi", + borrowed_bytes: &[0, 1, 2, 3], + }; + { + let encoded = serialize(&f).unwrap(); + let out: Foo = deserialize(&encoded[..]).unwrap(); + assert_eq!(out, f); + } +} + +#[test] +fn test_zero_copy_parse_deserialize_into() { + use bincode::BincodeRead; + use std::io; + + /// A BincodeRead implementation for byte slices + pub struct SliceReader<'storage> { + slice: &'storage [u8], + } + + impl<'storage> SliceReader<'storage> { + #[inline(always)] + fn unexpected_eof() -> Box<::ErrorKind> { + return Box::new(::ErrorKind::Io(io::Error::new( + io::ErrorKind::UnexpectedEof, + "", + ))); + } + } + + impl<'storage> io::Read for SliceReader<'storage> { + #[inline(always)] + fn read(&mut self, out: &mut [u8]) -> io::Result { + (&mut self.slice).read(out) + } + #[inline(always)] + fn read_exact(&mut self, out: &mut [u8]) -> io::Result<()> { + (&mut self.slice).read_exact(out) + } + } + + impl<'storage> BincodeRead<'storage> for SliceReader<'storage> { + #[inline(always)] + fn forward_read_str(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + use ErrorKind; + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let string = match ::std::str::from_utf8(&self.slice[..length]) { + Ok(s) => s, + Err(e) => return Err(ErrorKind::InvalidUtf8Encoding(e).into()), + }; + let r = visitor.visit_borrowed_str(string); + self.slice = &self.slice[length..]; + r + } + + #[inline(always)] + fn get_byte_buffer(&mut self, length: usize) -> Result> { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let r = &self.slice[..length]; + self.slice = &self.slice[length..]; + Ok(r.to_vec()) + } + + #[inline(always)] + fn forward_read_bytes(&mut self, length: usize, visitor: V) -> Result + where + V: serde::de::Visitor<'storage>, + { + if length > self.slice.len() { + return Err(SliceReader::unexpected_eof()); + } + + let r = visitor.visit_borrowed_bytes(&self.slice[..length]); + self.slice = &self.slice[length..]; + r + } + } + + #[derive(Serialize, Deserialize, Eq, PartialEq, Debug)] + struct Foo<'a> { + borrowed_str: &'a str, + borrowed_bytes: &'a [u8], + } + + let f = Foo { + borrowed_str: "hi", + borrowed_bytes: &[0, 1, 2, 3], + }; + + { + let encoded = serialize(&f).unwrap(); + let mut target = Foo { + borrowed_str: "hello", + borrowed_bytes: &[10, 11, 12, 13], + }; + deserialize_in_place( + SliceReader { + slice: &encoded[..], + }, + &mut target, + ) + .unwrap(); + assert_eq!(target, f); + } +} + +#[test] +fn not_human_readable() { + use std::net::Ipv4Addr; + let ip = Ipv4Addr::new(1, 2, 3, 4); + the_same(ip); + assert_eq!(&ip.octets()[..], &serialize(&ip).unwrap()[..]); + assert_eq!( + ::std::mem::size_of::() as u64, + serialized_size(&ip).unwrap() + ); +} + +// The example is taken from serde::de::DeserializeSeed. +struct ExtendVec<'a, T: 'a>(&'a mut Vec); + +impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T> +where + T: Deserialize<'de>, +{ + // The return type of the `deserialize` method. This implementation + // appends onto an existing vector but does not create any new data + // structure, so the return type is (). + type Value = (); + + fn deserialize(self, deserializer: D) -> StdResult + where + D: Deserializer<'de>, + { + // Visitor implementation that will walk an inner array of the JSON + // input. + struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec); + + impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "an array of integers") + } + + fn visit_seq(self, mut seq: A) -> StdResult<(), A::Error> + where + A: SeqAccess<'de>, + { + // Visit each element in the inner array and push it onto + // the existing vector. + while let Some(elem) = seq.next_element()? { + self.0.push(elem); + } + Ok(()) + } + } + + deserializer.deserialize_seq(ExtendVecVisitor(self.0)) + } +} + +#[test] +fn test_default_deserialize_seed() { + let config = DefaultOptions::new(); + + let data: Vec<_> = (10..100).collect(); + let bytes = config.serialize(&data).expect("Config::serialize failed"); + + let mut seed_data: Vec<_> = (0..10).collect(); + { + let seed = ExtendVec(&mut seed_data); + config + .deserialize_seed(seed, &bytes) + .expect("Config::deserialize_seed failed"); + } + + assert_eq!(seed_data, (0..100).collect::>()); +} + +#[test] +fn test_big_endian_deserialize_seed() { + let config = DefaultOptions::new().with_big_endian(); + + let data: Vec<_> = (10..100).collect(); + let bytes = config.serialize(&data).expect("Config::serialize failed"); + + let mut seed_data: Vec<_> = (0..10).collect(); + { + let seed = ExtendVec(&mut seed_data); + config + .deserialize_seed(seed, &bytes) + .expect("Config::deserialize_seed failed"); + } + + assert_eq!(seed_data, (0..100).collect::>()); +} + +#[test] +fn test_default_deserialize_from_seed() { + let config = DefaultOptions::new(); + + let data: Vec<_> = (10..100).collect(); + let bytes = config.serialize(&data).expect("Config::serialize failed"); + + let mut seed_data: Vec<_> = (0..10).collect(); + { + let seed = ExtendVec(&mut seed_data); + config + .deserialize_from_seed(seed, &mut &*bytes) + .expect("Config::deserialize_from_seed failed"); + } + + assert_eq!(seed_data, (0..100).collect::>()); +} + +#[test] +fn test_big_endian_deserialize_from_seed() { + let config = DefaultOptions::new().with_big_endian(); + + let data: Vec<_> = (10..100).collect(); + let bytes = config.serialize(&data).expect("Config::serialize failed"); + + let mut seed_data: Vec<_> = (0..10).collect(); + { + let seed = ExtendVec(&mut seed_data); + config + .deserialize_from_seed(seed, &mut &*bytes) + .expect("Config::deserialize_from_seed failed"); + } + + assert_eq!(seed_data, (0..100).collect::>()); +} + +#[test] +fn test_varint_length_prefixes() { + let a = vec![(); 127]; // should be a single byte + let b = vec![(); 250]; // also should be a single byte + let c = vec![(); 251]; + let d = vec![(); u16::max_value() as usize + 1]; + + assert_eq!( + DefaultOptions::new() + .with_varint_encoding() + .serialized_size(&a[..]) + .unwrap(), + 1 + ); // 2 ** 7 - 1 + assert_eq!( + DefaultOptions::new() + .with_varint_encoding() + .serialized_size(&b[..]) + .unwrap(), + 1 + ); // 250 + assert_eq!( + DefaultOptions::new() + .with_varint_encoding() + .serialized_size(&c[..]) + .unwrap(), + (1 + std::mem::size_of::()) as u64 + ); // 251 + assert_eq!( + DefaultOptions::new() + .with_varint_encoding() + .serialized_size(&d[..]) + .unwrap(), + (1 + std::mem::size_of::()) as u64 + ); // 2 ** 16 + 1 +} + +#[test] +fn test_byte_vec_struct() { + #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)] + struct ByteVecs { + a: Vec, + b: Vec, + c: Vec, + }; + + let byte_struct = ByteVecs { + a: vec![2; 20], + b: vec![3; 30], + c: vec![1; 10], + }; + + the_same(byte_struct); +} -- cgit v1.2.3