summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_cbor/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/serde_cbor/tests
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/serde_cbor/tests')
-rw-r--r--third_party/rust/serde_cbor/tests/bennofs.rs60
-rw-r--r--third_party/rust/serde_cbor/tests/canonical.rs104
-rw-r--r--third_party/rust/serde_cbor/tests/crash.cborbin0 -> 190 bytes
-rw-r--r--third_party/rust/serde_cbor/tests/de.rs747
-rw-r--r--third_party/rust/serde_cbor/tests/enum.rs236
-rw-r--r--third_party/rust/serde_cbor/tests/kietaub.cborbin0 -> 212 bytes
-rw-r--r--third_party/rust/serde_cbor/tests/ser.rs254
-rw-r--r--third_party/rust/serde_cbor/tests/std_types.rs186
-rw-r--r--third_party/rust/serde_cbor/tests/tags.rs48
-rw-r--r--third_party/rust/serde_cbor/tests/value.rs100
10 files changed, 1735 insertions, 0 deletions
diff --git a/third_party/rust/serde_cbor/tests/bennofs.rs b/third_party/rust/serde_cbor/tests/bennofs.rs
new file mode 100644
index 0000000000..1b289f40d4
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/bennofs.rs
@@ -0,0 +1,60 @@
+#[macro_use]
+extern crate serde_derive;
+
+use serde::Serialize;
+use serde_cbor::ser::SliceWrite;
+use serde_cbor::{self, Serializer};
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct Example {
+ foo: Foo,
+ payload: u8,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct Foo {
+ x: u8,
+ color: Color,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+enum Color {
+ Red,
+ Blue,
+ Yellow(u8),
+}
+
+const EXAMPLE: Example = Example {
+ foo: Foo {
+ x: 0xAA,
+ color: Color::Yellow(40),
+ },
+ payload: 0xCC,
+};
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ let serialized = serde_cbor::ser::to_vec_packed(&EXAMPLE).expect("bennofs 1");
+ println!("{:?}", serialized);
+ let deserialized: Example = serde_cbor::from_slice(&serialized).expect("bennofs 2");
+ assert_eq!(EXAMPLE, deserialized);
+ }
+}
+
+#[test]
+fn test() {
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer).packed_format();
+ EXAMPLE.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ let deserialized: Example =
+ serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+ assert_eq!(EXAMPLE, deserialized);
+}
diff --git a/third_party/rust/serde_cbor/tests/canonical.rs b/third_party/rust/serde_cbor/tests/canonical.rs
new file mode 100644
index 0000000000..438e29e7d4
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/canonical.rs
@@ -0,0 +1,104 @@
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde_cbor::value::Value;
+
+ #[test]
+ fn integer_canonical_sort_order() {
+ let expected = [
+ 0,
+ 23,
+ 24,
+ 255,
+ 256,
+ 65535,
+ 65536,
+ 4294967295,
+ -1,
+ -24,
+ -25,
+ -256,
+ -257,
+ -65536,
+ -65537,
+ -4294967296,
+ ]
+ .iter()
+ .map(|i| Value::Integer(*i))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn string_canonical_sort_order() {
+ let expected = ["", "a", "b", "aa"]
+ .iter()
+ .map(|s| Value::Text(s.to_string()))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn bytes_canonical_sort_order() {
+ let expected = vec![vec![], vec![0u8], vec![1u8], vec![0u8, 0u8]]
+ .into_iter()
+ .map(|v| Value::Bytes(v))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn simple_data_canonical_sort_order() {
+ let expected = vec![Value::Bool(false), Value::Bool(true), Value::Null];
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn major_type_canonical_sort_order() {
+ let expected = vec![
+ Value::Integer(0),
+ Value::Integer(-1),
+ Value::Bytes(vec![]),
+ Value::Text("".to_string()),
+ Value::Null,
+ ];
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn test_rfc_example() {
+ // See: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-4.10
+ let expected = vec![
+ Value::Integer(10),
+ Value::Integer(100),
+ Value::Integer(-1),
+ Value::Text("z".to_owned()),
+ Value::Text("aa".to_owned()),
+ Value::Array(vec![Value::Integer(100)]),
+ Value::Array(vec![Value::Integer(-1)]),
+ Value::Bool(false),
+ ];
+ let mut sorted = expected.clone();
+ sorted.sort();
+ assert_eq!(expected, sorted);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/crash.cbor b/third_party/rust/serde_cbor/tests/crash.cbor
new file mode 100644
index 0000000000..a3bc785ca3
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/crash.cbor
Binary files differ
diff --git a/third_party/rust/serde_cbor/tests/de.rs b/third_party/rust/serde_cbor/tests/de.rs
new file mode 100644
index 0000000000..01d7914502
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/de.rs
@@ -0,0 +1,747 @@
+#[macro_use]
+extern crate serde_derive;
+
+use serde_cbor;
+use serde_cbor::de;
+
+#[test]
+fn test_str() {
+ let s: &str =
+ de::from_slice_with_scratch(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72], &mut []).unwrap();
+ assert_eq!(s, "foobar");
+}
+
+#[test]
+fn test_bytes() {
+ let s: &[u8] =
+ de::from_slice_with_scratch(&[0x46, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72], &mut []).unwrap();
+ assert_eq!(s, b"foobar");
+}
+
+#[test]
+fn test_int() {
+ let num: i64 = de::from_slice_with_scratch(&[0x39, 0x07, 0xde], &mut []).unwrap();
+ assert_eq!(num, -2015);
+}
+
+#[test]
+fn test_float() {
+ let float: f64 = de::from_slice_with_scratch(b"\xfa\x47\xc3\x50\x00", &mut []).unwrap();
+ assert_eq!(float, 100000.0);
+}
+
+#[test]
+fn test_indefinite_object() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct Foo {
+ a: u64,
+ b: [u64; 2],
+ }
+ let expected = Foo { a: 1, b: [2, 3] };
+ let actual: Foo =
+ de::from_slice_with_scratch(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff", &mut []).unwrap();
+ assert_eq!(expected, actual);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::collections::BTreeMap;
+
+ use serde::de as serde_de;
+ use serde_cbor::value::Value;
+ use serde_cbor::{de, error, to_vec, Deserializer};
+
+ #[test]
+ fn test_string1() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ assert_eq!(value.unwrap(), Value::Text("foobar".to_owned()));
+ }
+
+ #[test]
+ fn test_string2() {
+ let value: error::Result<Value> = de::from_slice(&[
+ 0x71, 0x49, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x76, 0x65,
+ 0x6c, 0x6c, 0x65, 0x72,
+ ]);
+ assert_eq!(value.unwrap(), Value::Text("I met a traveller".to_owned()));
+ }
+
+ #[test]
+ fn test_string3() {
+ let slice = b"\x78\x2fI met a traveller from an antique land who said";
+ let value: error::Result<Value> = de::from_slice(slice);
+ assert_eq!(
+ value.unwrap(),
+ Value::Text("I met a traveller from an antique land who said".to_owned())
+ );
+ }
+
+ #[test]
+ fn test_byte_string() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0x46, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ assert_eq!(value.unwrap(), Value::Bytes(b"foobar".to_vec()));
+ }
+
+ #[test]
+ fn test_numbers1() {
+ let value: error::Result<Value> = de::from_slice(&[0x00]);
+ assert_eq!(value.unwrap(), Value::Integer(0));
+ }
+
+ #[test]
+ fn test_numbers2() {
+ let value: error::Result<Value> = de::from_slice(&[0x1a, 0x00, 0xbc, 0x61, 0x4e]);
+ assert_eq!(value.unwrap(), Value::Integer(12345678));
+ }
+
+ #[test]
+ fn test_numbers3() {
+ let value: error::Result<Value> = de::from_slice(&[0x39, 0x07, 0xde]);
+ assert_eq!(value.unwrap(), Value::Integer(-2015));
+ }
+
+ #[test]
+ fn test_bool() {
+ let value: error::Result<Value> = de::from_slice(b"\xf4");
+ assert_eq!(value.unwrap(), Value::Bool(false));
+ }
+
+ #[test]
+ fn test_trailing_bytes() {
+ let value: error::Result<Value> = de::from_slice(b"\xf4trailing");
+ assert!(value.is_err());
+ }
+
+ #[test]
+ fn test_list1() {
+ let value: error::Result<Value> = de::from_slice(b"\x83\x01\x02\x03");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ Value::Integer(3)
+ ])
+ );
+ }
+
+ #[test]
+ fn test_list2() {
+ let value: error::Result<Value> = de::from_slice(b"\x82\x01\x82\x02\x81\x03");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Array(vec![
+ Value::Integer(2),
+ Value::Array(vec![Value::Integer(3)])
+ ])
+ ])
+ );
+ }
+
+ #[test]
+ fn test_object() {
+ let value: error::Result<Value> = de::from_slice(b"\xa5aaaAabaBacaCadaDaeaE");
+ let mut object = BTreeMap::new();
+ object.insert(Value::Text("a".to_owned()), Value::Text("A".to_owned()));
+ object.insert(Value::Text("b".to_owned()), Value::Text("B".to_owned()));
+ object.insert(Value::Text("c".to_owned()), Value::Text("C".to_owned()));
+ object.insert(Value::Text("d".to_owned()), Value::Text("D".to_owned()));
+ object.insert(Value::Text("e".to_owned()), Value::Text("E".to_owned()));
+ assert_eq!(value.unwrap(), Value::Map(object));
+ }
+
+ #[test]
+ fn test_indefinite_object() {
+ let value: error::Result<Value> = de::from_slice(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff");
+ let mut object = BTreeMap::new();
+ object.insert(Value::Text("a".to_owned()), Value::Integer(1));
+ object.insert(
+ Value::Text("b".to_owned()),
+ Value::Array(vec![Value::Integer(2), Value::Integer(3)]),
+ );
+ assert_eq!(value.unwrap(), Value::Map(object));
+ }
+
+ #[test]
+ fn test_indefinite_list() {
+ let value: error::Result<Value> = de::from_slice(b"\x9f\x01\x02\x03\xff");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ Value::Integer(3)
+ ])
+ );
+ }
+
+ #[test]
+ fn test_indefinite_string() {
+ let value: error::Result<Value> =
+ de::from_slice(b"\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff");
+ assert_eq!(
+ value.unwrap(),
+ Value::Text("Mary Had a Little Lamb".to_owned())
+ );
+ }
+
+ #[test]
+ fn test_indefinite_byte_string() {
+ let value: error::Result<Value> = de::from_slice(b"\x5f\x42\x01\x23\x42\x45\x67\xff");
+ assert_eq!(value.unwrap(), Value::Bytes(b"\x01#Eg".to_vec()));
+ }
+
+ #[test]
+ fn test_multiple_indefinite_strings() {
+ let input = b"\x82\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff\x5f\x42\x01\x23\x42\x45\x67\xff";
+ _test_multiple_indefinite_strings(de::from_slice(input));
+ _test_multiple_indefinite_strings(de::from_mut_slice(input.to_vec().as_mut()));
+ let mut buf = [0u8; 64];
+ _test_multiple_indefinite_strings(de::from_slice_with_scratch(input, &mut buf));
+ }
+ fn _test_multiple_indefinite_strings(value: error::Result<Value>) {
+ // This assures that buffer rewinding in infinite buffers works as intended.
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Text("Mary Had a Little Lamb".to_owned()),
+ Value::Bytes(b"\x01#Eg".to_vec())
+ ])
+ );
+ }
+
+ #[test]
+ fn test_float() {
+ let value: error::Result<Value> = de::from_slice(b"\xfa\x47\xc3\x50\x00");
+ assert_eq!(value.unwrap(), Value::Float(100000.0));
+ }
+
+ #[test]
+ fn test_self_describing() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0xd9, 0xd9, 0xf7, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ let expected = Value::Text("foobar".to_owned());
+ let strip_tags = |x: Value| {
+ if let Value::Tag(_, inner) = x {
+ *inner
+ } else {
+ x
+ }
+ };
+ assert_eq!(strip_tags(value.unwrap()), expected);
+ }
+
+ #[test]
+ fn test_f16() {
+ let mut x: Value = de::from_slice(&[0xf9, 0x41, 0x00]).unwrap();
+ assert_eq!(x, Value::Float(2.5));
+ x = de::from_slice(&[0xf9, 0x41, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(2.78125));
+ x = de::from_slice(&[0xf9, 0x50, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(36.5));
+ x = de::from_slice(&[0xf9, 0xd0, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(-36.5));
+ }
+
+ #[test]
+ fn test_crazy_list() {
+ let slice = b"\x88\x1b\x00\x00\x00\x1c\xbe\x99\x1d\xc7\x3b\x00\x7a\xcf\x51\xdc\x51\x70\xdb\x3a\x1b\x3a\x06\xdd\xf5\xf6\xf7\xfb\x41\x76\x5e\xb1\xf8\x00\x00\x00\xf9\x7c\x00";
+ let value: Vec<Value> = de::from_slice(slice).unwrap();
+ assert_eq!(
+ value,
+ vec![
+ Value::Integer(123456789959),
+ Value::Integer(-34567897654325468),
+ Value::Integer(-456787678),
+ Value::Bool(true),
+ Value::Null,
+ Value::Null,
+ Value::Float(23456543.5),
+ Value::Float(::std::f64::INFINITY)
+ ]
+ );
+ }
+
+ #[test]
+ fn test_nan() {
+ let value: f64 = de::from_slice(b"\xf9\x7e\x00").unwrap();
+ assert!(value.is_nan());
+ }
+
+ #[test]
+ fn test_32f16() {
+ let value: f32 = de::from_slice(b"\xf9\x50\x00").unwrap();
+ assert_eq!(value, 32.0f32);
+ }
+
+ #[test]
+ // The file was reported as not working by user kie0tauB
+ // but it parses to a cbor value.
+ fn test_kietaub_file() {
+ let file = include_bytes!("kietaub.cbor");
+ let value_result: error::Result<Value> = de::from_slice(file);
+ value_result.unwrap();
+ }
+
+ #[test]
+ fn test_option_roundtrip() {
+ let obj1 = Some(10u32);
+
+ let v = to_vec(&obj1).unwrap();
+ let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
+ println!("{:?}", obj2);
+
+ assert_eq!(obj1, obj2.unwrap());
+ }
+
+ #[test]
+ fn test_option_none_roundtrip() {
+ let obj1 = None;
+
+ let v = to_vec(&obj1).unwrap();
+ println!("{:?}", v);
+ let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
+
+ assert_eq!(obj1, obj2.unwrap());
+ }
+
+ #[test]
+ fn test_variable_length_map() {
+ let slice = b"\xbf\x67\x6d\x65\x73\x73\x61\x67\x65\x64\x70\x6f\x6e\x67\xff";
+ let value: Value = de::from_slice(slice).unwrap();
+ let mut map = BTreeMap::new();
+ map.insert(
+ Value::Text("message".to_string()),
+ Value::Text("pong".to_string()),
+ );
+ assert_eq!(value, Value::Map(map))
+ }
+
+ #[test]
+ fn test_object_determinism_roundtrip() {
+ let expected = b"\xa2aa\x01ab\x82\x02\x03";
+
+ // 0.1% chance of not catching failure
+ for _ in 0..10 {
+ assert_eq!(
+ &to_vec(&de::from_slice::<Value>(expected).unwrap()).unwrap(),
+ expected
+ );
+ }
+ }
+
+ #[test]
+ fn stream_deserializer() {
+ let slice = b"\x01\x66foobar";
+ let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
+ assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
+ assert_eq!(
+ Value::Text("foobar".to_string()),
+ it.next().unwrap().unwrap()
+ );
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn stream_deserializer_eof() {
+ let slice = b"\x01\x66foob";
+ let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
+ assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+ }
+
+ #[test]
+ fn stream_deserializer_eof_in_indefinite() {
+ let slice = b"\x7f\x65Mary \x64Had \x62a \x60\x67Little \x60\x64Lamb\xff";
+ let indices: &[usize] = &[
+ 2, // announcement but no data
+ 10, // mid-buffer EOF
+ 12, // neither new element nor end marker
+ ];
+ for end_of_slice in indices {
+ let mut it = Deserializer::from_slice(&slice[..*end_of_slice]).into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+
+ let mut mutcopy = slice[..*end_of_slice].to_vec();
+ let mut it = Deserializer::from_mut_slice(mutcopy.as_mut()).into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+
+ let mut buf = [0u8; 64];
+ let mut it = Deserializer::from_slice_with_scratch(&slice[..*end_of_slice], &mut buf)
+ .into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+ }
+ }
+
+ #[test]
+ fn crash() {
+ let file = include_bytes!("crash.cbor");
+ let value_result: error::Result<Value> = de::from_slice(file);
+ assert_eq!(
+ value_result.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ fn from_slice_stream<'a, T>(slice: &'a [u8]) -> error::Result<(&'a [u8], T)>
+ where
+ T: serde_de::Deserialize<'a>,
+ {
+ let mut deserializer = Deserializer::from_slice(slice);
+ let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
+ let rest = &slice[deserializer.byte_offset()..];
+
+ Ok((rest, value))
+ }
+
+ #[test]
+ fn test_slice_offset() {
+ let v: Vec<u8> = vec![
+ 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72,
+ ];
+ let (rest, value): (&[u8], String) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, "foobar");
+ assert_eq!(rest, &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ let (rest, value): (&[u8], String) = from_slice_stream(rest).unwrap();
+ assert_eq!(value, "foobar");
+ assert_eq!(rest, &[]);
+ }
+
+ #[derive(Debug, Copy, Clone)]
+ struct Options {
+ standard: bool,
+ legacy: bool,
+ packed: bool,
+ named: bool,
+ }
+
+ impl Default for Options {
+ fn default() -> Self {
+ Options {
+ standard: true,
+ legacy: true,
+ packed: true,
+ named: true,
+ }
+ }
+ }
+
+ impl Options {
+ fn no_standard(self) -> Self {
+ Options {
+ standard: false,
+ ..self
+ }
+ }
+
+ fn no_legacy(self) -> Self {
+ Options {
+ legacy: false,
+ ..self
+ }
+ }
+
+ fn no_packed(self) -> Self {
+ Options {
+ packed: false,
+ ..self
+ }
+ }
+
+ fn no_named(self) -> Self {
+ Options {
+ named: false,
+ ..self
+ }
+ }
+ }
+
+ fn from_slice_stream_options<'a, T>(
+ slice: &'a [u8],
+ options: Options,
+ ) -> error::Result<(&'a [u8], T)>
+ where
+ T: serde_de::Deserialize<'a>,
+ {
+ let deserializer = Deserializer::from_slice(slice);
+ let deserializer = if !options.packed {
+ deserializer.disable_packed_format()
+ } else {
+ deserializer
+ };
+ let deserializer = if !options.named {
+ deserializer.disable_named_format()
+ } else {
+ deserializer
+ };
+ let deserializer = if !options.standard {
+ deserializer.disable_standard_enums()
+ } else {
+ deserializer
+ };
+ let mut deserializer = if !options.legacy {
+ deserializer.disable_legacy_enums()
+ } else {
+ deserializer
+ };
+ let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
+ let rest = &slice[deserializer.byte_offset()..];
+
+ Ok((rest, value))
+ }
+
+ #[test]
+ fn test_deserializer_enums() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ enum Enum {
+ Unit,
+ NewType(i32),
+ Tuple(String, bool),
+ Struct { x: i32, y: i32 },
+ }
+
+ // This is the format used in serde >= 0.10
+ //
+ // Serialization of Enum::NewType(10)
+ let v: Vec<u8> = vec![
+ 0xa1, // map 1pair
+ 0x67, 0x4e, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, // utf8 string: NewType
+ 0x1a, // u32
+ 0x00, 0x00, 0x00, 0x0a, // 10 (dec)
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ // Serialization of Enum::Unit
+ let v: Vec<u8> = vec![
+ 0x64, 0x55, 0x6e, 0x69, 0x74, // utf8 string: Unit
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_standard()).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_legacy().no_standard());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // This is the format used in serde <= 0.9
+ let v: Vec<u8> = vec![
+ 0x82, // array 2 items
+ 0x67, 0x4e, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, // utf8 string: NewType
+ 0x1a, // u32
+ 0x00, 0x00, 0x00, 0x0a, // 10 (dec)
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard());
+ assert_eq!(value.unwrap().1, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ #[test]
+ fn test_packed_deserialization() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct User {
+ user_id: u32,
+ password_hash: [u8; 4],
+ }
+
+ // unpacked
+ let v: Vec<u8> = vec![
+ 0xa2, // map 2pair
+ 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, // utf8 string: user_id
+ 0x0a, // integer: 10
+ // utf8 string: password_hash
+ 0x6d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68,
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_named());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // unpacked - indefinite length
+ let v: Vec<u8> = vec![
+ 0xbf, // map to be followed by a break
+ 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, // utf8 string: user_id
+ 0x0a, // integer: 10
+ // utf8 string: password_hash
+ 0x6d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68,
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ 0xff, // break
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_named());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // packed
+ let v: Vec<u8> = vec![
+ 0xa2, // map 2pair
+ 0x00, // index 0
+ 0x0a, // integer: 10
+ 0x01, // index 1
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_packed());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // packed - indefinite length
+ let v: Vec<u8> = vec![
+ 0xbf, // map, to be followed by a break
+ 0x00, // index 0
+ 0x0a, // integer: 10
+ 0x01, // index 1
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ 0xff, // break
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_packed());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ use serde_cbor::{de::from_slice, ser::to_vec_packed};
+ use std::net::{IpAddr, Ipv4Addr};
+ #[test]
+ fn test_ipaddr_deserialization() {
+ let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+ let buf = to_vec_packed(&ip).unwrap();
+ let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
+ assert_eq!(ip, deserialized_ip);
+
+ let buf = to_vec(&ip).unwrap();
+ let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
+ assert_eq!(ip, deserialized_ip);
+ }
+
+ #[test]
+ fn attempt_stack_overflow() {
+ // Create a tag 17, followed by 999 more tag 17:
+ // 17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(...
+ // This causes deep recursion in the decoder and may
+ // exhaust the stack and therfore result in a stack overflow.
+ let input = vec![0xd1; 1000];
+ let err = serde_cbor::from_slice::<serde_cbor::Value>(&input).expect_err("recursion limit");
+ assert!(err.is_syntax());
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/enum.rs b/third_party/rust/serde_cbor/tests/enum.rs
new file mode 100644
index 0000000000..630500d6b5
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/enum.rs
@@ -0,0 +1,236 @@
+use serde::Serialize;
+use serde_cbor;
+use serde_cbor::ser::{Serializer, SliceWrite};
+
+#[macro_use]
+extern crate serde_derive;
+
+#[test]
+fn test_simple_data_enum_roundtrip() {
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum DataEnum {
+ A(u32),
+ B(f32),
+ }
+
+ let a = DataEnum::A(42);
+
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer);
+ a.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ let deserialized: DataEnum =
+ serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+ assert_eq!(a, deserialized);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::collections::BTreeMap;
+
+ use serde_cbor::ser::{IoWrite, Serializer};
+ use serde_cbor::value::Value;
+ use serde_cbor::{from_slice, to_vec};
+
+ pub fn to_vec_legacy<T>(value: &T) -> serde_cbor::Result<Vec<u8>>
+ where
+ T: serde::ser::Serialize,
+ {
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).legacy_enums())?;
+ Ok(vec)
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum Enum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ struct EnumStruct {
+ e: Enum,
+ }
+
+ #[test]
+ fn test_enum() {
+ let enum_struct = EnumStruct { e: Enum::B };
+ let raw = &to_vec(&enum_struct).unwrap();
+ println!("raw enum {:?}", raw);
+ let re: EnumStruct = from_slice(raw).unwrap();
+ assert_eq!(enum_struct, re);
+ }
+
+ #[repr(u16)]
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum ReprEnum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ struct ReprEnumStruct {
+ e: ReprEnum,
+ }
+
+ #[test]
+ fn test_repr_enum() {
+ let repr_enum_struct = ReprEnumStruct { e: ReprEnum::B };
+ let re: ReprEnumStruct = from_slice(&to_vec(&repr_enum_struct).unwrap()).unwrap();
+ assert_eq!(repr_enum_struct, re);
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum DataEnum {
+ A(u32),
+ B(bool, u8),
+ C { x: u8, y: String },
+ }
+
+ #[test]
+ fn test_data_enum() {
+ let data_enum_a = DataEnum::A(4);
+ let re_a: DataEnum = from_slice(&to_vec(&data_enum_a).unwrap()).unwrap();
+ assert_eq!(data_enum_a, re_a);
+ let data_enum_b = DataEnum::B(true, 42);
+ let re_b: DataEnum = from_slice(&to_vec(&data_enum_b).unwrap()).unwrap();
+ assert_eq!(data_enum_b, re_b);
+ let data_enum_c = DataEnum::C {
+ x: 3,
+ y: "foo".to_owned(),
+ };
+ println!("{:?}", &to_vec(&data_enum_c).unwrap());
+ let re_c: DataEnum = from_slice(&to_vec(&data_enum_c).unwrap()).unwrap();
+ assert_eq!(data_enum_c, re_c);
+ }
+
+ #[test]
+ fn test_serialize() {
+ assert_eq!(to_vec_legacy(&Enum::A).unwrap(), &[97, 65]);
+ assert_eq!(to_vec_legacy(&Enum::B).unwrap(), &[97, 66]);
+ assert_eq!(
+ to_vec_legacy(&DataEnum::A(42)).unwrap(),
+ &[130, 97, 65, 24, 42]
+ );
+ assert_eq!(
+ to_vec_legacy(&DataEnum::B(true, 9)).unwrap(),
+ &[131, 97, 66, 245, 9]
+ );
+ }
+
+ #[test]
+ fn test_newtype_struct() {
+ #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
+ pub struct Newtype(u8);
+ assert_eq!(to_vec(&142u8).unwrap(), to_vec(&Newtype(142u8)).unwrap());
+ assert_eq!(from_slice::<Newtype>(&[24, 142]).unwrap(), Newtype(142));
+ }
+
+ #[derive(Deserialize, PartialEq, Debug)]
+ enum Foo {
+ #[serde(rename = "require")]
+ Require,
+ }
+
+ #[test]
+ fn test_variable_length_array() {
+ let slice = b"\x9F\x67\x72\x65\x71\x75\x69\x72\x65\xFF";
+ let value: Vec<Foo> = from_slice(slice).unwrap();
+ assert_eq!(value, [Foo::Require]);
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Bar {
+ Empty,
+ Number(i32),
+ Flag(String, bool),
+ Point { x: i32, y: i32 },
+ }
+
+ #[test]
+ fn test_enum_as_map() {
+ // unit variants serialize like bare strings
+ let empty_s = to_vec_legacy(&Bar::Empty).unwrap();
+ let empty_str_s = to_vec_legacy(&"Empty").unwrap();
+ assert_eq!(empty_s, empty_str_s);
+
+ // tuple-variants serialize like ["<variant>", values..]
+ let number_s = to_vec_legacy(&Bar::Number(42)).unwrap();
+ let number_vec = vec![Value::Text("Number".to_string()), Value::Integer(42)];
+ let number_vec_s = to_vec_legacy(&number_vec).unwrap();
+ assert_eq!(number_s, number_vec_s);
+
+ let flag_s = to_vec_legacy(&Bar::Flag("foo".to_string(), true)).unwrap();
+ let flag_vec = vec![
+ Value::Text("Flag".to_string()),
+ Value::Text("foo".to_string()),
+ Value::Bool(true),
+ ];
+ let flag_vec_s = to_vec_legacy(&flag_vec).unwrap();
+ assert_eq!(flag_s, flag_vec_s);
+
+ // struct-variants serialize like ["<variant>", {struct..}]
+ let point_s = to_vec_legacy(&Bar::Point { x: 5, y: -5 }).unwrap();
+ let mut struct_map = BTreeMap::new();
+ struct_map.insert(Value::Text("x".to_string()), Value::Integer(5));
+ struct_map.insert(Value::Text("y".to_string()), Value::Integer(-5));
+ let point_vec = vec![
+ Value::Text("Point".to_string()),
+ Value::Map(struct_map.clone()),
+ ];
+ let point_vec_s = to_vec_legacy(&point_vec).unwrap();
+ assert_eq!(point_s, point_vec_s);
+
+ // enum_as_map matches serde_json's default serialization for enums.
+
+ // unit variants still serialize like bare strings
+ let empty_s = to_vec(&Bar::Empty).unwrap();
+ assert_eq!(empty_s, empty_str_s);
+
+ // 1-element tuple variants serialize like {"<variant>": value}
+ let number_s = to_vec(&Bar::Number(42)).unwrap();
+ let mut number_map = BTreeMap::new();
+ number_map.insert("Number", 42);
+ let number_map_s = to_vec(&number_map).unwrap();
+ assert_eq!(number_s, number_map_s);
+
+ // multi-element tuple variants serialize like {"<variant>": [values..]}
+ let flag_s = to_vec(&Bar::Flag("foo".to_string(), true)).unwrap();
+ let mut flag_map = BTreeMap::new();
+ flag_map.insert(
+ "Flag",
+ vec![Value::Text("foo".to_string()), Value::Bool(true)],
+ );
+ let flag_map_s = to_vec(&flag_map).unwrap();
+ assert_eq!(flag_s, flag_map_s);
+
+ // struct-variants serialize like {"<variant>", {struct..}}
+ let point_s = to_vec(&Bar::Point { x: 5, y: -5 }).unwrap();
+ let mut point_map = BTreeMap::new();
+ point_map.insert("Point", Value::Map(struct_map));
+ let point_map_s = to_vec(&point_map).unwrap();
+ assert_eq!(point_s, point_map_s);
+
+ // deserialization of all encodings should just work
+ let empty_str_ds = from_slice(&empty_str_s).unwrap();
+ assert_eq!(Bar::Empty, empty_str_ds);
+
+ let number_vec_ds = from_slice(&number_vec_s).unwrap();
+ assert_eq!(Bar::Number(42), number_vec_ds);
+ let number_map_ds = from_slice(&number_map_s).unwrap();
+ assert_eq!(Bar::Number(42), number_map_ds);
+
+ let flag_vec_ds = from_slice(&flag_vec_s).unwrap();
+ assert_eq!(Bar::Flag("foo".to_string(), true), flag_vec_ds);
+ let flag_map_ds = from_slice(&flag_map_s).unwrap();
+ assert_eq!(Bar::Flag("foo".to_string(), true), flag_map_ds);
+
+ let point_vec_ds = from_slice(&point_vec_s).unwrap();
+ assert_eq!(Bar::Point { x: 5, y: -5 }, point_vec_ds);
+ let point_map_ds = from_slice(&point_map_s).unwrap();
+ assert_eq!(Bar::Point { x: 5, y: -5 }, point_map_ds);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/kietaub.cbor b/third_party/rust/serde_cbor/tests/kietaub.cbor
new file mode 100644
index 0000000000..866a093132
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/kietaub.cbor
Binary files differ
diff --git a/third_party/rust/serde_cbor/tests/ser.rs b/third_party/rust/serde_cbor/tests/ser.rs
new file mode 100644
index 0000000000..d374ce2faf
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/ser.rs
@@ -0,0 +1,254 @@
+use serde::Serialize;
+use serde_cbor::ser::{Serializer, SliceWrite};
+
+#[test]
+fn test_str() {
+ serialize_and_compare("foobar", b"ffoobar");
+}
+
+#[test]
+fn test_list() {
+ serialize_and_compare(&[1, 2, 3], b"\x83\x01\x02\x03");
+}
+
+#[test]
+fn test_float() {
+ serialize_and_compare(12.3f64, b"\xfb@(\x99\x99\x99\x99\x99\x9a");
+}
+
+#[test]
+fn test_integer() {
+ // u8
+ serialize_and_compare(24, b"\x18\x18");
+ // i8
+ serialize_and_compare(-5, b"\x24");
+ // i16
+ serialize_and_compare(-300, b"\x39\x01\x2b");
+ // i32
+ serialize_and_compare(-23567997, b"\x3a\x01\x67\x9e\x7c");
+ // u64
+ serialize_and_compare(::core::u64::MAX, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
+}
+
+fn serialize_and_compare<T: Serialize>(value: T, expected: &[u8]) {
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer);
+ value.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ assert_eq!(&slice[..end], expected);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde::Serializer;
+ use serde_cbor::ser;
+ use serde_cbor::{from_slice, to_vec};
+ use std::collections::BTreeMap;
+
+ #[test]
+ fn test_string() {
+ let value = "foobar".to_owned();
+ assert_eq!(&to_vec(&value).unwrap()[..], b"ffoobar");
+ }
+
+ #[test]
+ fn test_list() {
+ let value = vec![1, 2, 3];
+ assert_eq!(&to_vec(&value).unwrap()[..], b"\x83\x01\x02\x03");
+ }
+
+ #[test]
+ fn test_object() {
+ let mut object = BTreeMap::new();
+ object.insert("a".to_owned(), "A".to_owned());
+ object.insert("b".to_owned(), "B".to_owned());
+ object.insert("c".to_owned(), "C".to_owned());
+ object.insert("d".to_owned(), "D".to_owned());
+ object.insert("e".to_owned(), "E".to_owned());
+ let vec = to_vec(&object).unwrap();
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_object_list_keys() {
+ let mut object = BTreeMap::new();
+ object.insert(vec![0i64], ());
+ object.insert(vec![100i64], ());
+ object.insert(vec![-1i64], ());
+ object.insert(vec![-2i64], ());
+ object.insert(vec![0i64, 0i64], ());
+ object.insert(vec![0i64, -1i64], ());
+ let vec = to_vec(&serde_cbor::value::to_value(object.clone()).unwrap()).unwrap();
+ assert_eq!(
+ vec![
+ 166, 129, 0, 246, 129, 24, 100, 246, 129, 32, 246, 129, 33, 246, 130, 0, 0, 246,
+ 130, 0, 32, 246
+ ],
+ vec
+ );
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_object_object_keys() {
+ use std::iter::FromIterator;
+ let mut object = BTreeMap::new();
+ let keys = vec![
+ vec!["a"],
+ vec!["b"],
+ vec!["c"],
+ vec!["d"],
+ vec!["aa"],
+ vec!["a", "aa"],
+ ]
+ .into_iter()
+ .map(|v| BTreeMap::from_iter(v.into_iter().map(|s| (s.to_owned(), ()))));
+
+ for key in keys {
+ object.insert(key, ());
+ }
+ let vec = to_vec(&serde_cbor::value::to_value(object.clone()).unwrap()).unwrap();
+ assert_eq!(
+ vec![
+ 166, 161, 97, 97, 246, 246, 161, 97, 98, 246, 246, 161, 97, 99, 246, 246, 161, 97,
+ 100, 246, 246, 161, 98, 97, 97, 246, 246, 162, 97, 97, 246, 98, 97, 97, 246, 246
+ ],
+ vec
+ );
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_float() {
+ let vec = to_vec(&12.3f64).unwrap();
+ assert_eq!(vec, b"\xfb@(\x99\x99\x99\x99\x99\x9a");
+ }
+
+ #[test]
+ fn test_f32() {
+ let vec = to_vec(&4000.5f32).unwrap();
+ assert_eq!(vec, b"\xfa\x45\x7a\x08\x00");
+ }
+
+ #[test]
+ fn test_infinity() {
+ let vec = to_vec(&::std::f64::INFINITY).unwrap();
+ assert_eq!(vec, b"\xf9|\x00");
+ }
+
+ #[test]
+ fn test_neg_infinity() {
+ let vec = to_vec(&::std::f64::NEG_INFINITY).unwrap();
+ assert_eq!(vec, b"\xf9\xfc\x00");
+ }
+
+ #[test]
+ fn test_nan() {
+ let vec = to_vec(&::std::f32::NAN).unwrap();
+ assert_eq!(vec, b"\xf9\x7e\x00");
+ }
+
+ #[test]
+ fn test_integer() {
+ // u8
+ let vec = to_vec(&24).unwrap();
+ assert_eq!(vec, b"\x18\x18");
+ // i8
+ let vec = to_vec(&-5).unwrap();
+ assert_eq!(vec, b"\x24");
+ // i16
+ let vec = to_vec(&-300).unwrap();
+ assert_eq!(vec, b"\x39\x01\x2b");
+ // i32
+ let vec = to_vec(&-23567997).unwrap();
+ assert_eq!(vec, b"\x3a\x01\x67\x9e\x7c");
+ // u64
+ let vec = to_vec(&::std::u64::MAX).unwrap();
+ assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
+ }
+
+ #[test]
+ fn test_self_describing() {
+ let mut vec = Vec::new();
+ {
+ let mut serializer = ser::Serializer::new(&mut vec);
+ serializer.self_describe().unwrap();
+ serializer.serialize_u64(9).unwrap();
+ }
+ assert_eq!(vec, b"\xd9\xd9\xf7\x09");
+ }
+
+ #[test]
+ fn test_ip_addr() {
+ use std::net::Ipv4Addr;
+
+ let addr = Ipv4Addr::new(8, 8, 8, 8);
+ let vec = to_vec(&addr).unwrap();
+ println!("{:?}", vec);
+ assert_eq!(vec.len(), 5);
+ let test_addr: Ipv4Addr = from_slice(&vec).unwrap();
+ assert_eq!(addr, test_addr);
+ }
+
+ /// Test all of CBOR's fixed-length byte string types
+ #[test]
+ fn test_byte_string() {
+ // Very short byte strings have 1-byte headers
+ let short = vec![0, 1, 2, 255];
+ let mut short_s = Vec::new();
+ serde_cbor::Serializer::new(&mut short_s)
+ .serialize_bytes(&short)
+ .unwrap();
+ assert_eq!(&short_s[..], [0x44, 0, 1, 2, 255]);
+
+ // byte strings > 23 bytes have 2-byte headers
+ let medium = vec![
+ 0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 255,
+ ];
+ let mut medium_s = Vec::new();
+ serde_cbor::Serializer::new(&mut medium_s)
+ .serialize_bytes(&medium)
+ .unwrap();
+ assert_eq!(
+ &medium_s[..],
+ [
+ 0x58, 24, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 255
+ ]
+ );
+
+ // byte strings > 256 bytes have 3-byte headers
+ let long_vec = (0..256).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>();
+ let mut long_s = Vec::new();
+ serde_cbor::Serializer::new(&mut long_s)
+ .serialize_bytes(&long_vec)
+ .unwrap();
+ assert_eq!(&long_s[0..3], [0x59, 1, 0]);
+ assert_eq!(&long_s[3..], &long_vec[..]);
+
+ // byte strings > 2^16 bytes have 5-byte headers
+ let very_long_vec = (0..65536).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>();
+ let mut very_long_s = Vec::new();
+ serde_cbor::Serializer::new(&mut very_long_s)
+ .serialize_bytes(&very_long_vec)
+ .unwrap();
+ assert_eq!(&very_long_s[0..5], [0x5a, 0, 1, 0, 0]);
+ assert_eq!(&very_long_s[5..], &very_long_vec[..]);
+
+ // byte strings > 2^32 bytes have 9-byte headers, but they take too much RAM
+ // to test in Travis.
+ }
+
+ #[test]
+ fn test_half() {
+ let vec = to_vec(&42.5f32).unwrap();
+ assert_eq!(vec, b"\xF9\x51\x50");
+ assert_eq!(from_slice::<f32>(&vec[..]).unwrap(), 42.5f32);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/std_types.rs b/third_party/rust/serde_cbor/tests/std_types.rs
new file mode 100644
index 0000000000..7a7ded484c
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/std_types.rs
@@ -0,0 +1,186 @@
+#[macro_use]
+extern crate serde_derive;
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::u8;
+
+ use serde_cbor::de::from_mut_slice;
+ use serde_cbor::ser::{to_vec, to_vec_packed};
+ use serde_cbor::{from_reader, from_slice};
+
+ fn to_binary(s: &'static str) -> Vec<u8> {
+ assert!(s.len() % 2 == 0);
+ let mut b = Vec::with_capacity(s.len() / 2);
+ for i in 0..s.len() / 2 {
+ b.push(u8::from_str_radix(&s[i * 2..(i + 1) * 2], 16).unwrap());
+ }
+ b
+ }
+
+ macro_rules! testcase {
+ ($name:ident, f64, $expr:expr, $s:expr) => {
+ #[test]
+ fn $name() {
+ let expr: f64 = $expr;
+ let mut serialized = to_binary($s);
+ assert_eq!(to_vec(&expr).unwrap(), serialized);
+ let parsed: f64 = from_slice(&serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+
+ let parsed: f64 = from_reader(&mut &serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+
+ let parsed: f64 = from_mut_slice(&mut serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+ }
+ };
+ ($name:ident, $ty:ty, $expr:expr, $s:expr) => {
+ #[test]
+ fn $name() {
+ let expr: $ty = $expr;
+ let mut serialized = to_binary($s);
+ assert_eq!(
+ to_vec(&expr).expect("ser1 works"),
+ serialized,
+ "serialization differs"
+ );
+ let parsed: $ty = from_slice(&serialized[..]).expect("de1 works");
+ assert_eq!(parsed, expr, "parsed result differs");
+ let packed = &to_vec_packed(&expr).expect("serializing packed")[..];
+ let parsed_from_packed: $ty = from_slice(packed).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+
+ let parsed: $ty = from_reader(&mut &serialized[..]).unwrap();
+ assert_eq!(parsed, expr, "parsed result differs");
+ let mut packed = to_vec_packed(&expr).expect("serializing packed");
+ let parsed_from_packed: $ty =
+ from_reader(&mut &packed[..]).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+
+ let parsed: $ty = from_mut_slice(&mut serialized[..]).unwrap();
+ assert_eq!(parsed, expr, "parsed result differs");
+ let parsed_from_packed: $ty =
+ from_mut_slice(&mut packed[..]).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+ }
+ };
+ }
+
+ testcase!(test_bool_false, bool, false, "f4");
+ testcase!(test_bool_true, bool, true, "f5");
+ testcase!(test_isize_neg_256, isize, -256, "38ff");
+ testcase!(test_isize_neg_257, isize, -257, "390100");
+ testcase!(test_isize_255, isize, 255, "18ff");
+ testcase!(test_i8_5, i8, 5, "05");
+ testcase!(test_i8_23, i8, 23, "17");
+ testcase!(test_i8_24, i8, 24, "1818");
+ testcase!(test_i8_neg_128, i8, -128, "387f");
+ testcase!(test_u32_98745874, u32, 98745874, "1a05e2be12");
+ testcase!(test_f32_1234_point_5, f32, 1234.5, "fa449a5000");
+ testcase!(test_f64_12345_point_6, f64, 12345.6, "fb40c81ccccccccccd");
+ testcase!(test_f64_nan, f64, ::std::f64::NAN, "f97e00");
+ testcase!(test_f64_infinity, f64, ::std::f64::INFINITY, "f97c00");
+ testcase!(test_f64_neg_infinity, f64, -::std::f64::INFINITY, "f9fc00");
+ testcase!(test_char_null, char, '\x00', "6100");
+ testcase!(test_char_broken_heart, char, '💔', "64f09f9294");
+ testcase!(
+ test_str_pangram_de,
+ String,
+ "aâø↓é".to_owned(),
+ "6a61c3a2c3b8e28693c3a9"
+ );
+ testcase!(test_unit, (), (), "f6");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct UnitStruct;
+ testcase!(test_unit_struct, UnitStruct, UnitStruct, "f6");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct NewtypeStruct(bool);
+ testcase!(
+ test_newtype_struct,
+ NewtypeStruct,
+ NewtypeStruct(true),
+ "f5"
+ );
+
+ testcase!(test_option_none, Option<u8>, None, "f6");
+ testcase!(test_option_some, Option<u8>, Some(42), "182a");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct Person {
+ name: String,
+ year_of_birth: u16,
+ profession: Option<String>,
+ }
+
+ testcase!(test_person_struct,
+ Person,
+ Person {
+ name: "Grace Hopper".to_string(),
+ year_of_birth: 1906,
+ profession: Some("computer scientist".to_string()),
+ },
+ "a3646e616d656c477261636520486f707065726d796561725f6f665f62697274681907726a70726f66657373696f6e72636f6d707574657220736369656e74697374");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct OptionalPerson {
+ name: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ year_of_birth: Option<u16>,
+ profession: Option<String>,
+ }
+
+ testcase!(test_optional_person_struct,
+ OptionalPerson,
+ OptionalPerson {
+ name: "Grace Hopper".to_string(),
+ year_of_birth: None,
+ profession: Some("computer scientist".to_string()),
+ },
+ "a2646e616d656c477261636520486f707065726a70726f66657373696f6e72636f6d707574657220736369656e74697374");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ enum Color {
+ Red,
+ Blue,
+ Yellow,
+ Other(u64),
+ Alpha(u64, u8),
+ }
+
+ testcase!(test_color_enum, Color, Color::Blue, "64426c7565");
+ testcase!(
+ test_color_enum_transparent,
+ Color,
+ Color::Other(42),
+ "a1654f74686572182a"
+ );
+ testcase!(
+ test_color_enum_with_alpha,
+ Color,
+ Color::Alpha(234567, 60),
+ "a165416c706861821a00039447183c"
+ );
+ testcase!(test_i128_a, i128, -1i128, "20");
+ testcase!(
+ test_i128_b,
+ i128,
+ -18446744073709551616i128,
+ "3BFFFFFFFFFFFFFFFF"
+ );
+ testcase!(test_u128, u128, 17, "11");
+}
diff --git a/third_party/rust/serde_cbor/tests/tags.rs b/third_party/rust/serde_cbor/tests/tags.rs
new file mode 100644
index 0000000000..92534c023d
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/tags.rs
@@ -0,0 +1,48 @@
+#[cfg(feature = "tags")]
+mod tagtests {
+ use serde_cbor::value::Value;
+ use serde_cbor::{from_slice, to_vec};
+
+ fn decode_hex(s: &str) -> std::result::Result<Vec<u8>, std::num::ParseIntError> {
+ (0..s.len())
+ .step_by(2)
+ .map(|i| u8::from_str_radix(&s[i..i + 2], 16))
+ .collect()
+ }
+
+ // get bytes from http://cbor.me/ trees
+ fn parse_cbor_me(example: &str) -> std::result::Result<Vec<u8>, std::num::ParseIntError> {
+ let hex = example
+ .split("\n")
+ .flat_map(|line| line.split("#").take(1))
+ .collect::<Vec<&str>>()
+ .join("")
+ .replace(" ", "");
+ decode_hex(&hex)
+ }
+
+ #[test]
+ fn tagged_cbor_roundtrip() {
+ let data = r#"
+C1 # tag(1)
+ 82 # array(2)
+ C2 # tag(2)
+ 63 # text(3)
+ 666F6F # "foo"
+ C3 # tag(3)
+ A1 # map(1)
+ C4 # tag(4)
+ 61 # text(1)
+ 61 # "a"
+ C5 # tag(5)
+ 61 # text(1)
+ 62 # "b"
+ "#;
+ let bytes1 = parse_cbor_me(&data).unwrap();
+ let value1: Value = from_slice(&bytes1).unwrap();
+ let bytes2 = to_vec(&value1).unwrap();
+ let value2: Value = from_slice(&bytes2).unwrap();
+ assert_eq!(bytes1, bytes2);
+ assert_eq!(value1, value2);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/value.rs b/third_party/rust/serde_cbor/tests/value.rs
new file mode 100644
index 0000000000..554d74266c
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/value.rs
@@ -0,0 +1,100 @@
+#[macro_use]
+extern crate serde_derive;
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde_cbor;
+
+ use std::collections::BTreeMap;
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct TupleStruct(String, i32, u64);
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct UnitStruct;
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct Struct<'a> {
+ tuple_struct: TupleStruct,
+ tuple: (String, f32, f64),
+ map: BTreeMap<String, String>,
+ bytes: &'a [u8],
+ array: Vec<String>,
+ unit_array: Vec<UnitStruct>,
+ }
+
+ use serde_cbor::value::Value;
+ use std::iter::FromIterator;
+
+ #[test]
+ fn serde() {
+ let tuple_struct = TupleStruct(format!("test"), -60, 3000);
+
+ let tuple = (format!("hello"), -50.0040957, -12.094635556478);
+
+ let map = BTreeMap::from_iter(
+ [
+ (format!("key1"), format!("value1")),
+ (format!("key2"), format!("value2")),
+ (format!("key3"), format!("value3")),
+ (format!("key4"), format!("value4")),
+ ]
+ .iter()
+ .cloned(),
+ );
+
+ let bytes = b"test byte string";
+
+ let array = vec![format!("one"), format!("two"), format!("three")];
+ let unit_array = vec![UnitStruct, UnitStruct, UnitStruct];
+
+ let data = Struct {
+ tuple_struct,
+ tuple,
+ map,
+ bytes,
+ array,
+ unit_array,
+ };
+
+ let value = serde_cbor::value::to_value(data.clone()).unwrap();
+ println!("{:?}", value);
+
+ let data_ser = serde_cbor::to_vec(&value).unwrap();
+ let data_de_value: Value = serde_cbor::from_slice(&data_ser).unwrap();
+
+ fn as_object(value: &Value) -> &BTreeMap<Value, Value> {
+ if let Value::Map(ref v) = value {
+ return v;
+ }
+ panic!()
+ }
+
+ for ((k1, v1), (k2, v2)) in as_object(&value)
+ .iter()
+ .zip(as_object(&data_de_value).iter())
+ {
+ assert_eq!(k1, k2);
+ assert_eq!(v1, v2);
+ }
+
+ assert_eq!(value, data_de_value);
+ }
+
+ #[derive(Debug, Deserialize, Serialize)]
+ struct SmallStruct {
+ spam: u32,
+ eggs: u32,
+ }
+
+ #[test]
+ fn small_struct() {
+ // Test whether the packed format works.
+ // Field names should not be serialized,
+ // instead field indizes are serialized.
+ let value = SmallStruct { spam: 17, eggs: 42 };
+ let data = serde_cbor::ser::to_vec_packed(&value).unwrap();
+ let reference = b"\xa2\x00\x11\x01\x18\x2a";
+ assert_eq!(data, reference);
+ }
+}