| #[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<V, O>(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<V>(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::<usize>); | |
| } | |
| #[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<u8> = 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::<bool>(&vec![0xA][..]).unwrap_err() { | |
| ErrorKind::InvalidBoolEncoding(0xA) => {} | |
| _ => panic!(), | |
| } | |
| let invalid_str = vec![1, 0, 0, 0, 0, 0, 0, 0, 0xFF]; | |
| match *deserialize::<String>(&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::<Test>(&invalid_enum[..]).unwrap_err() { | |
| // Error message comes from serde | |
| ErrorKind::Custom(_) => {} | |
| _ => panic!(), | |
| } | |
| match *deserialize::<Option<u8>>(&vec![5, 0][..]).unwrap_err() { | |
| ErrorKind::InvalidTagEncoding(_) => {} | |
| _ => panic!(), | |
| } | |
| } | |
| #[test] | |
| fn trailing_bytes() { | |
| match DefaultOptions::new() | |
| .deserialize::<char>(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<u32> = 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<u32> = 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<char> = 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<u32>>), | |
| M2(Cow<'a, HashMap<u32, u32>>), | |
| } | |
| // 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<u32>> = deserialize_from(&mut &serialized[..]).unwrap(); | |
| { | |
| let sb: &[u32] = &deserialized; | |
| assert!(slice == sb); | |
| } | |
| let vecx: Vec<u32> = 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<Vec<u8>> = 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<usize> { | |
| (&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<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> | |
| 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<Vec<u8>> { | |
| 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<V>(&mut self, length: usize, visitor: V) -> Result<V::Value> | |
| 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::<Ipv4Addr>() as u64, | |
| serialized_size(&ip).unwrap() | |
| ); | |
| } | |
| // The example is taken from serde::de::DeserializeSeed. | |
| struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>); | |
| 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<D>(self, deserializer: D) -> StdResult<Self::Value, D::Error> | |
| where | |
| D: Deserializer<'de>, | |
| { | |
| // Visitor implementation that will walk an inner array of the JSON | |
| // input. | |
| struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>); | |
| 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<A>(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::<Vec<_>>()); | |
| } | |
| #[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::<Vec<_>>()); | |
| } | |
| #[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::<Vec<_>>()); | |
| } | |
| #[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::<Vec<_>>()); | |
| } | |
| #[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::<u16>()) as u64 | |
| ); // 251 | |
| assert_eq!( | |
| DefaultOptions::new() | |
| .with_varint_encoding() | |
| .serialized_size(&d[..]) | |
| .unwrap(), | |
| (1 + std::mem::size_of::<u32>()) as u64 | |
| ); // 2 ** 16 + 1 | |
| } | |
| #[test] | |
| fn test_byte_vec_struct() { | |
| #[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)] | |
| struct ByteVecs { | |
| a: Vec<u8>, | |
| b: Vec<u8>, | |
| c: Vec<u8>, | |
| }; | |
| let byte_struct = ByteVecs { | |
| a: vec![2; 20], | |
| b: vec![3; 30], | |
| c: vec![1; 10], | |
| }; | |
| the_same(byte_struct); | |
| } |