diff --git a/ciborium-ll/src/lib.rs b/ciborium-ll/src/lib.rs index 8a1fe90..c02ba49 100644 --- a/ciborium-ll/src/lib.rs +++ b/ciborium-ll/src/lib.rs @@ -460,6 +460,11 @@ mod tests { Header::Break, ], ), + ("c340", &[Header::Tag(3), Header::Bytes(Some(0))]), + ( + "c35fff", + &[Header::Tag(3), Header::Bytes(None), Header::Break], + ), ]; for (bytes, headers) in data { diff --git a/ciborium/src/de/mod.rs b/ciborium/src/de/mod.rs index 7c6bcad..b858759 100644 --- a/ciborium/src/de/mod.rs +++ b/ciborium/src/de/mod.rs @@ -10,7 +10,10 @@ use alloc::{string::String, vec::Vec}; use ciborium_io::Read; use ciborium_ll::*; -use serde::{de, de::Deserializer as _, forward_to_deserialize_any}; +use serde::{ + de::{self, value::BytesDeserializer, Deserializer as _}, + forward_to_deserialize_any, +}; trait Expected { fn expected(self, kind: &'static str) -> E; @@ -72,7 +75,11 @@ where } #[inline] - fn integer(&mut self, mut header: Option
) -> Result<(bool, u128), Error> { + fn integer( + &mut self, + mut header: Option
, + mut append: Option, + ) -> Result<(bool, u128), Error> { loop { let header = match header.take() { Some(h) => h, @@ -99,7 +106,22 @@ where while let Some(chunk) = segment.pull(&mut buffer)? { for b in chunk { match index { - 16 => return Err(de::Error::custom("bigint too large")), + 16 => { + if let Some(app) = append.as_mut() { + for v in value { + app(v); + } + app(*b); + index = 17; // Indicate overflow, see below + continue; + } + return Err(de::Error::custom("bigint too large")); + } + 17 => { + // append is not None + append.as_mut().unwrap()(*b); + continue; + } 0 if *b == 0 => continue, // Skip leading zeros _ => value[index] = *b, } @@ -109,8 +131,12 @@ where } } - value[..index].reverse(); - Ok((neg, u128::from_le_bytes(value))) + if index == 17 { + Ok((false, 0)) + } else { + value[..index].reverse(); + Ok((neg, u128::from_le_bytes(value))) + } } h => Err(h.expected("bytes")), @@ -157,18 +183,21 @@ where let header = self.decoder.pull()?; self.decoder.push(header); - // If it is bytes, capture the length. - let len = match header { - Header::Bytes(x) => x, - _ => None, - }; - - match (tag, len) { - (tag::BIGPOS, Some(len)) | (tag::BIGNEG, Some(len)) if len <= 16 => { - let result = match self.integer(Some(Header::Tag(tag)))? { - (false, raw) => return visitor.visit_u128(raw), - (true, raw) => i128::try_from(raw).map(|x| x ^ !0), - }; + match tag { + tag::BIGPOS | tag::BIGNEG => { + let mut bytes = Vec::new(); + let result = + match self.integer(Some(Header::Tag(tag)), Some(|b| bytes.push(b)))? { + (false, _) if !bytes.is_empty() => { + let access = crate::tag::TagAccess::new( + BytesDeserializer::new(&bytes), + Some(tag), + ); + return visitor.visit_enum(access); + } + (false, raw) => return visitor.visit_u128(raw), + (true, raw) => i128::try_from(raw).map(|x| x ^ !0), + }; match result { Ok(x) => visitor.visit_i128(x), @@ -238,7 +267,7 @@ where } fn deserialize_i64>(self, visitor: V) -> Result { - let result = match self.integer(None)? { + let result = match self.integer(None, None::)? { (false, raw) => i64::try_from(raw), (true, raw) => i64::try_from(raw).map(|x| x ^ !0), }; @@ -250,7 +279,7 @@ where } fn deserialize_i128>(self, visitor: V) -> Result { - let result = match self.integer(None)? { + let result = match self.integer(None, None::)? { (false, raw) => i128::try_from(raw), (true, raw) => i128::try_from(raw).map(|x| x ^ !0), }; @@ -274,7 +303,7 @@ where } fn deserialize_u64>(self, visitor: V) -> Result { - let result = match self.integer(None)? { + let result = match self.integer(None, None::)? { (false, raw) => u64::try_from(raw), (true, ..) => return Err(de::Error::custom("unexpected negative integer")), }; @@ -286,7 +315,7 @@ where } fn deserialize_u128>(self, visitor: V) -> Result { - match self.integer(None)? { + match self.integer(None, None::)? { (false, raw) => visitor.visit_u128(raw), (true, ..) => Err(de::Error::custom("unexpected negative integer")), } diff --git a/ciborium/tests/codec.rs b/ciborium/tests/codec.rs index d737059..99f1030 100644 --- a/ciborium/tests/codec.rs +++ b/ciborium/tests/codec.rs @@ -36,244 +36,248 @@ macro_rules! map { // Keep the first "case" aligned to a line number ending in 1 for ease in finding tests. #[allow(clippy::excessive_precision)] -#[rstest(input, value, bytes, alternate, equality, - - case(0u8, val!(0u8), "00", false, same), - case(0u16, val!(0u16), "00", false, same), - case(0u32, val!(0u32), "00", false, same), - case(0u64, val!(0u64), "00", false, same), - case(0u128, val!(0u128), "00", false, same), - case(0i8, val!(0i8), "00", false, same), - case(0i16, val!(0i16), "00", false, same), - case(0i32, val!(0i32), "00", false, same), - case(0i64, val!(0i64), "00", false, same), - case(0i128, val!(0i128), "00", false, same), - case(1u8, val!(1u8), "01", false, same), - case(1u16, val!(1u16), "01", false, same), - case(1u32, val!(1u32), "01", false, same), - case(1u64, val!(1u64), "01", false, same), - case(1u128, val!(1u128), "01", false, same), - case(1i8, val!(1i8), "01", false, same), - case(1i16, val!(1i16), "01", false, same), - case(1i32, val!(1i32), "01", false, same), - case(1i64, val!(1i64), "01", false, same), - case(1i128, val!(1i128), "01", false, same), - case(1u8, val!(1u8), "1b0000000000000001", true, same), - case(1u16, val!(1u16), "1b0000000000000001", true, same), - case(1u32, val!(1u32), "1b0000000000000001", true, same), - case(1u64, val!(1u64), "1b0000000000000001", true, same), - case(1u128, val!(1u128), "1b0000000000000001", true, same), - case(1i8, val!(1i8), "1b0000000000000001", true, same), - case(1i16, val!(1i16), "1b0000000000000001", true, same), - case(1i32, val!(1i32), "1b0000000000000001", true, same), - case(1i64, val!(1i64), "1b0000000000000001", true, same), - case(1i128, val!(1i128), "1b0000000000000001", true, same), - case(1u8, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1u16, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1u32, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1u64, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1u128, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1i8, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1i16, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1i32, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1i64, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(1i128, bigint(), "c2540000000000000000000000000000000000000001", true, same), // Not In RFC - case(10u8, val!(10u8), "0a", false, same), - case(10u16, val!(10u16), "0a", false, same), - case(10u32, val!(10u32), "0a", false, same), - case(10u64, val!(10u64), "0a", false, same), - case(10u128, val!(10u128), "0a", false, same), - case(10i8, val!(10i8), "0a", false, same), - case(10i16, val!(10i16), "0a", false, same), - case(10i32, val!(10i32), "0a", false, same), - case(10i64, val!(10i64), "0a", false, same), - case(10i128, val!(10i128), "0a", false, same), - case(23u8, val!(23u8), "17", false, same), - case(23u16, val!(23u16), "17", false, same), - case(23u32, val!(23u32), "17", false, same), - case(23u64, val!(23u64), "17", false, same), - case(23u128, val!(23u128), "17", false, same), - case(23i8, val!(23i8), "17", false, same), - case(23i16, val!(23i16), "17", false, same), - case(23i32, val!(23i32), "17", false, same), - case(23i64, val!(23i64), "17", false, same), - case(23i128, val!(23i128), "17", false, same), - case(24u8, val!(24u8), "1818", false, same), - case(24u16, val!(24u16), "1818", false, same), - case(24u32, val!(24u32), "1818", false, same), - case(24u64, val!(24u64), "1818", false, same), - case(24u128, val!(24u128), "1818", false, same), - case(24i8, val!(24i8), "1818", false, same), - case(24i16, val!(24i16), "1818", false, same), - case(24i32, val!(24i32), "1818", false, same), - case(24i64, val!(24i64), "1818", false, same), - case(24i128, val!(24i128), "1818", false, same), - case(25u8, val!(25u8), "1819", false, same), - case(25u16, val!(25u16), "1819", false, same), - case(25u32, val!(25u32), "1819", false, same), - case(25u64, val!(25u64), "1819", false, same), - case(25u128, val!(25u128), "1819", false, same), - case(25i8, val!(25i8), "1819", false, same), - case(25i16, val!(25i16), "1819", false, same), - case(25i32, val!(25i32), "1819", false, same), - case(25i64, val!(25i64), "1819", false, same), - case(25i128, val!(25i128), "1819", false, same), - case(100u8, val!(100u8), "1864", false, same), - case(100u16, val!(100u16), "1864", false, same), - case(100u32, val!(100u32), "1864", false, same), - case(100u64, val!(100u64), "1864", false, same), - case(100u128, val!(100u128), "1864", false, same), - case(100i8, val!(100i8), "1864", false, same), - case(100i16, val!(100i16), "1864", false, same), - case(100i32, val!(100i32), "1864", false, same), - case(100i64, val!(100i64), "1864", false, same), - case(100i128, val!(100i128), "1864", false, same), - case(1000u16, val!(1000u16), "1903e8", false, same), - case(1000u32, val!(1000u32), "1903e8", false, same), - case(1000u64, val!(1000u64), "1903e8", false, same), - case(1000u128, val!(1000u128), "1903e8", false, same), - case(1000i16, val!(1000i16), "1903e8", false, same), - case(1000i32, val!(1000i32), "1903e8", false, same), - case(1000i64, val!(1000i64), "1903e8", false, same), - case(1000i128, val!(1000i128), "1903e8", false, same), - case(1000000u32, val!(1000000u32), "1a000f4240", false, same), - case(1000000u64, val!(1000000u64), "1a000f4240", false, same), - case(1000000u128, val!(1000000u128), "1a000f4240", false, same), - case(1000000i32, val!(1000000i32), "1a000f4240", false, same), - case(1000000i64, val!(1000000i64), "1a000f4240", false, same), - case(1000000i128, val!(1000000i128), "1a000f4240", false, same), - case(1000000000000u64, val!(1000000000000u64), "1b000000e8d4a51000", false, same), - case(1000000000000u128, val!(1000000000000u128), "1b000000e8d4a51000", false, same), - case(1000000000000i64, val!(1000000000000i64), "1b000000e8d4a51000", false, same), - case(1000000000000i128, val!(1000000000000i128), "1b000000e8d4a51000", false, same), - case(18446744073709551615u64, val!(18446744073709551615u64), "1bffffffffffffffff", false, same), - case(18446744073709551615u128, val!(18446744073709551615u128), "1bffffffffffffffff", false, same), - case(18446744073709551615i128, val!(18446744073709551615i128), "1bffffffffffffffff", false, same), - case(18446744073709551616u128, val!(18446744073709551616u128), "c249010000000000000000", false, same), - case(18446744073709551616i128, val!(18446744073709551616i128), "c249010000000000000000", false, same), - case(-18446744073709551617i128, val!(-18446744073709551617i128), "c349010000000000000000", false, same), - case(-18446744073709551616i128, val!(-18446744073709551616i128), "3bffffffffffffffff", false, same), - case(-1000i16, val!(-1000i16), "3903e7", false, same), - case(-1000i32, val!(-1000i32), "3903e7", false, same), - case(-1000i64, val!(-1000i64), "3903e7", false, same), - case(-1000i128, val!(-1000i128), "3903e7", false, same), - case(-100i8, val!(-100i8), "3863", false, same), - case(-100i16, val!(-100i16), "3863", false, same), - case(-100i32, val!(-100i32), "3863", false, same), - case(-100i64, val!(-100i64), "3863", false, same), - case(-100i128, val!(-100i128), "3863", false, same), - case(-10i8, val!(-10i8), "29", false, same), - case(-10i16, val!(-10i16), "29", false, same), - case(-10i32, val!(-10i32), "29", false, same), - case(-10i64, val!(-10i64), "29", false, same), - case(-10i128, val!(-10i128), "29", false, same), - case(-1i8, val!(-1i8), "20", false, same), - case(-1i16, val!(-1i16), "20", false, same), - case(-1i32, val!(-1i32), "20", false, same), - case(-1i64, val!(-1i64), "20", false, same), - case(-1i128, val!(-1i128), "20", false, same), - case(-1i8, val!(-1i8), "3b0000000000000000", true, same), - case(-1i16, val!(-1i16), "3b0000000000000000", true, same), - case(-1i32, val!(-1i32), "3b0000000000000000", true, same), - case(-1i64, val!(-1i64), "3b0000000000000000", true, same), - case(-1i128, val!(-1i128), "3b0000000000000000", true, same), - case(0.0f32, val!(0.0f32), "f90000", false, Float), - case(0.0f64, val!(0.0f64), "f90000", false, Float), - case(-0.0f32, val!(-0.0f32), "f98000", false, Float), - case(-0.0f64, val!(-0.0f64), "f98000", false, Float), - case(1.0f32, val!(1.0f32), "f93c00", false, Float), - case(1.0f64, val!(1.0f64), "f93c00", false, Float), - case(1.1f32, val!(1.1f32), "fa3f8ccccd", false, Float), // Not In RFC - case(1.1f64, val!(1.1f64), "fb3ff199999999999a", false, Float), - case(1.5f32, val!(1.5f32), "f93e00", false, Float), - case(1.5f64, val!(1.5f64), "f93e00", false, Float), - case(65504.0f32, val!(65504.0f32), "f97bff", false, Float), - case(65504.0f64, val!(65504.0f64), "f97bff", false, Float), - case(100000.0f32, val!(100000.0f32), "fa47c35000", false, Float), - case(100000.0f64, val!(100000.0f64), "fa47c35000", false, Float), - case(3.4028234663852886e+38f32, val!(3.4028234663852886e+38f32), "fa7f7fffff", false, Float), - case(3.4028234663852886e+38f64, val!(3.4028234663852886e+38f64), "fa7f7fffff", false, Float), - case(1.0e+300f64, val!(1.0e+300f64), "fb7e37e43c8800759c", false, Float), - case(5.960464477539063e-8f32, val!(5.960464477539063e-8f32), "f90001", false, Float), - case(5.960464477539063e-8f64, val!(5.960464477539063e-8f64), "f90001", false, Float), - case(0.00006103515625f32, val!(0.00006103515625f32), "f90400", false, Float), - case(0.00006103515625f64, val!(0.00006103515625f64), "f90400", false, Float), - case(-4.0f32, val!(-4.0f32), "f9c400", false, Float), - case(-4.0f64, val!(-4.0f64), "f9c400", false, Float), - case(-4.1f32, val!(-4.1f32), "fac0833333", false, Float), // Not In RFC - case(-4.1f64, val!(-4.1f64), "fbc010666666666666", false, Float), - case(core::f32::INFINITY, val!(core::f32::INFINITY), "f97c00", false, Float), - case(core::f64::INFINITY, val!(core::f64::INFINITY), "f97c00", false, Float), - case(core::f32::INFINITY, val!(core::f32::INFINITY), "fa7f800000", true, Float), - case(core::f64::INFINITY, val!(core::f64::INFINITY), "fa7f800000", true, Float), - case(core::f32::INFINITY, val!(core::f32::INFINITY), "fb7ff0000000000000", true, Float), - case(core::f64::INFINITY, val!(core::f64::INFINITY), "fb7ff0000000000000", true, Float), - case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "f9fc00", false, Float), - case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "f9fc00", false, Float), - case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "faff800000", true, Float), - case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "faff800000", true, Float), - case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "fbfff0000000000000", true, Float), - case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "fbfff0000000000000", true, Float), - case(core::f32::NAN, val!(core::f32::NAN), "f97e00", false, Float), - case(core::f64::NAN, val!(core::f64::NAN), "f97e00", false, Float), - case(core::f32::NAN, val!(core::f32::NAN), "fa7fc00000", true, Float), - case(core::f64::NAN, val!(core::f64::NAN), "fa7fc00000", true, Float), - case(core::f32::NAN, val!(core::f32::NAN), "fb7ff8000000000000", true, Float), - case(core::f64::NAN, val!(core::f64::NAN), "fb7ff8000000000000", true, Float), - case(-core::f32::NAN, val!(-core::f32::NAN), "f9fe00", false, Float), // Not In RFC - case(-core::f64::NAN, val!(-core::f64::NAN), "f9fe00", false, Float), // Not In RFC - case(-core::f32::NAN, val!(-core::f32::NAN), "faffc00000", true, Float), // Not In RFC - case(-core::f64::NAN, val!(-core::f64::NAN), "faffc00000", true, Float), // Not In RFC - case(-core::f32::NAN, val!(-core::f32::NAN), "fbfff8000000000000", true, Float), // Not In RFC - case(-core::f64::NAN, val!(-core::f64::NAN), "fbfff8000000000000", true, Float), // Not In RFC - case(false, val!(false), "f4", false, same), - case(true, val!(true), "f5", false, same), - case(Value::Null, Value::Null, "f6", false, same), - case(hex!(""), val!(&b""[..]), "40", false, same), - case(hex!("01020304"), val!(&b"\x01\x02\x03\x04"[..]), "4401020304", false, same), - case(hex!("0102030405"), val!(&b"\x01\x02\x03\x04\x05"[..]), "5f42010243030405ff", true, same), - case("", val!(""), "60", false, ToOwned::to_owned), - case("a", val!("a"), "6161", false, ToOwned::to_owned), - case('a', val!('a'), "6161", false, same), - case("IETF", val!("IETF"), "6449455446", false, ToOwned::to_owned), - case("\"\\", val!("\"\\"), "62225c", false, ToOwned::to_owned), - case("ü", val!("ü"), "62c3bc", false, ToOwned::to_owned), - case('ü', val!('ü'), "62c3bc", false, same), - case("水", val!("水"), "63e6b0b4", false, ToOwned::to_owned), - case('水', val!('水'), "63e6b0b4", false, same), - case("𐅑", val!("𐅑"), "64f0908591", false, ToOwned::to_owned), - case('𐅑', val!('𐅑'), "64f0908591", false, same), - case("streaming", val!("streaming"), "7f657374726561646d696e67ff", true, ToOwned::to_owned), - case(cbor!([]).unwrap(), Vec::::new().into(), "80", false, same), - case(cbor!([]).unwrap(), Vec::::new().into(), "9fff", true, same), - case(cbor!([1, 2, 3]).unwrap(), cbor!([1, 2, 3]).unwrap(), "83010203", false, same), - case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "8301820203820405", false, same), - case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "9f018202039f0405ffff", true, same), - case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "9f01820203820405ff", true, same), - case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "83018202039f0405ff", true, same), - case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "83019f0203ff820405", true, same), - case((1..=25).collect::>(), (1..=25).map(|x| x.into()).collect::>().into(), "98190102030405060708090a0b0c0d0e0f101112131415161718181819", false, same), - case((1..=25).collect::>(), (1..=25).map(|x| x.into()).collect::>().into(), "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff", true, same), - case(HashMap::::new(), Value::Map(vec![]), "a0", false, same), - case(BTreeMap::::new(), Value::Map(vec![]), "a0", false, same), - case(map!{1 => 2, 3 => 4}, cbor!({1 => 2, 3 => 4}).unwrap(), "a201020304", false, same), - case(cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), "a26161016162820203", false, same), - case(cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), "bf61610161629f0203ffff", true, same), - case(cbor!(["a", {"b" => "c"}]).unwrap(), cbor!(["a", {"b" => "c"}]).unwrap(), "826161a161626163", false, same), - case(cbor!(["a", {"b" => "c"}]).unwrap(), cbor!(["a", {"b" => "c"}]).unwrap(), "826161bf61626163ff", true, same), - case(cbor!({"Fun" => true, "Amt" => -2}).unwrap(), cbor!({"Fun" => true, "Amt" => -2}).unwrap(), "bf6346756ef563416d7421ff", true, same), - case(map_big(), vmap_big(), "a56161614161626142616361436164614461656145", false, same), - case(Option::::None, Value::Null, "f6", false, same), // Not In RFC - case(Option::Some(7u8), val!(7u8), "07", false, same), // Not In RFC - case((), Value::Null, "f6", false, same), // Not In RFC - case(UnitStruct, Value::Null, "f6", false, same), // Not In RFC - case(Newtype(123), val!(123u8), "187b", false, same), // Not In RFC - case((22u8, 23u16), cbor!([22, 23]).unwrap(), "821617", false, same), // Not In RFC - case(TupleStruct(33, 34), cbor!([33, 34]).unwrap(), "8218211822", false, same), // Not In RFC - case(Enum::Unit, cbor!("Unit").unwrap(), "64556e6974", false, same), // Not In RFC - case(Enum::Newtype(45), cbor!({"Newtype" => 45}).unwrap(), "a1674e657774797065182d", false, same), // Not In RFC - case(Enum::Tuple(56, 67), cbor!({"Tuple" => [56, 67]}).unwrap(), "a1655475706c658218381843", false, same), // Not In RFC - case(Enum::Struct { first: 78, second: 89 }, cbor!({ "Struct" => { "first" => 78, "second" => 89 }}).unwrap(), "a166537472756374a2656669727374184e667365636f6e641859", false, same), // Not In RFC +#[rstest(input, value, bytes, alternate, equality, round_trip, + + case(0u8, val!(0u8), "00", false, same, None), + case(0u16, val!(0u16), "00", false, same, None), + case(0u32, val!(0u32), "00", false, same, None), + case(0u64, val!(0u64), "00", false, same, None), + case(0u128, val!(0u128), "00", false, same, None), + case(0i8, val!(0i8), "00", false, same, None), + case(0i16, val!(0i16), "00", false, same, None), + case(0i32, val!(0i32), "00", false, same, None), + case(0i64, val!(0i64), "00", false, same, None), + case(0i128, val!(0i128), "00", false, same, None), + case(1u8, val!(1u8), "01", false, same, None), + case(1u16, val!(1u16), "01", false, same, None), + case(1u32, val!(1u32), "01", false, same, None), + case(1u64, val!(1u64), "01", false, same, None), + case(1u128, val!(1u128), "01", false, same, None), + case(1i8, val!(1i8), "01", false, same, None), + case(1i16, val!(1i16), "01", false, same, None), + case(1i32, val!(1i32), "01", false, same, None), + case(1i64, val!(1i64), "01", false, same, None), + case(1i128, val!(1i128), "01", false, same, None), + case(1u8, val!(1u8), "1b0000000000000001", true, same, None), + case(1u16, val!(1u16), "1b0000000000000001", true, same, None), + case(1u32, val!(1u32), "1b0000000000000001", true, same, None), + case(1u64, val!(1u64), "1b0000000000000001", true, same, None), + case(1u128, val!(1u128), "1b0000000000000001", true, same, None), + case(1i8, val!(1i8), "1b0000000000000001", true, same, None), + case(1i16, val!(1i16), "1b0000000000000001", true, same, None), + case(1i32, val!(1i32), "1b0000000000000001", true, same, None), + case(1i64, val!(1i64), "1b0000000000000001", true, same, None), + case(1i128, val!(1i128), "1b0000000000000001", true, same, None), + case(1u8, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1u16, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1u32, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1u64, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1u128, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1i8, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1i16, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1i32, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1i64, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(1i128, val!(1), "c2540000000000000000000000000000000000000001", true, same, None), // Not In RFC + case(10u8, val!(10u8), "0a", false, same, None), + case(10u16, val!(10u16), "0a", false, same, None), + case(10u32, val!(10u32), "0a", false, same, None), + case(10u64, val!(10u64), "0a", false, same, None), + case(10u128, val!(10u128), "0a", false, same, None), + case(10i8, val!(10i8), "0a", false, same, None), + case(10i16, val!(10i16), "0a", false, same, None), + case(10i32, val!(10i32), "0a", false, same, None), + case(10i64, val!(10i64), "0a", false, same, None), + case(10i128, val!(10i128), "0a", false, same, None), + case(23u8, val!(23u8), "17", false, same, None), + case(23u16, val!(23u16), "17", false, same, None), + case(23u32, val!(23u32), "17", false, same, None), + case(23u64, val!(23u64), "17", false, same, None), + case(23u128, val!(23u128), "17", false, same, None), + case(23i8, val!(23i8), "17", false, same, None), + case(23i16, val!(23i16), "17", false, same, None), + case(23i32, val!(23i32), "17", false, same, None), + case(23i64, val!(23i64), "17", false, same, None), + case(23i128, val!(23i128), "17", false, same, None), + case(24u8, val!(24u8), "1818", false, same, None), + case(24u16, val!(24u16), "1818", false, same, None), + case(24u32, val!(24u32), "1818", false, same, None), + case(24u64, val!(24u64), "1818", false, same, None), + case(24u128, val!(24u128), "1818", false, same, None), + case(24i8, val!(24i8), "1818", false, same, None), + case(24i16, val!(24i16), "1818", false, same, None), + case(24i32, val!(24i32), "1818", false, same, None), + case(24i64, val!(24i64), "1818", false, same, None), + case(24i128, val!(24i128), "1818", false, same, None), + case(25u8, val!(25u8), "1819", false, same, None), + case(25u16, val!(25u16), "1819", false, same, None), + case(25u32, val!(25u32), "1819", false, same, None), + case(25u64, val!(25u64), "1819", false, same, None), + case(25u128, val!(25u128), "1819", false, same, None), + case(25i8, val!(25i8), "1819", false, same, None), + case(25i16, val!(25i16), "1819", false, same, None), + case(25i32, val!(25i32), "1819", false, same, None), + case(25i64, val!(25i64), "1819", false, same, None), + case(25i128, val!(25i128), "1819", false, same, None), + case(100u8, val!(100u8), "1864", false, same, None), + case(100u16, val!(100u16), "1864", false, same, None), + case(100u32, val!(100u32), "1864", false, same, None), + case(100u64, val!(100u64), "1864", false, same, None), + case(100u128, val!(100u128), "1864", false, same, None), + case(100i8, val!(100i8), "1864", false, same, None), + case(100i16, val!(100i16), "1864", false, same, None), + case(100i32, val!(100i32), "1864", false, same, None), + case(100i64, val!(100i64), "1864", false, same, None), + case(100i128, val!(100i128), "1864", false, same, None), + case(1000u16, val!(1000u16), "1903e8", false, same, None), + case(1000u32, val!(1000u32), "1903e8", false, same, None), + case(1000u64, val!(1000u64), "1903e8", false, same, None), + case(1000u128, val!(1000u128), "1903e8", false, same, None), + case(1000i16, val!(1000i16), "1903e8", false, same, None), + case(1000i32, val!(1000i32), "1903e8", false, same, None), + case(1000i64, val!(1000i64), "1903e8", false, same, None), + case(1000i128, val!(1000i128), "1903e8", false, same, None), + case(1000000u32, val!(1000000u32), "1a000f4240", false, same, None), + case(1000000u64, val!(1000000u64), "1a000f4240", false, same, None), + case(1000000u128, val!(1000000u128), "1a000f4240", false, same, None), + case(1000000i32, val!(1000000i32), "1a000f4240", false, same, None), + case(1000000i64, val!(1000000i64), "1a000f4240", false, same, None), + case(1000000i128, val!(1000000i128), "1a000f4240", false, same, None), + case(1000000000000u64, val!(1000000000000u64), "1b000000e8d4a51000", false, same, None), + case(1000000000000u128, val!(1000000000000u128), "1b000000e8d4a51000", false, same, None), + case(1000000000000i64, val!(1000000000000i64), "1b000000e8d4a51000", false, same, None), + case(1000000000000i128, val!(1000000000000i128), "1b000000e8d4a51000", false, same, None), + case(18446744073709551615u64, val!(18446744073709551615u64), "1bffffffffffffffff", false, same, None), + case(18446744073709551615u128, val!(18446744073709551615u128), "1bffffffffffffffff", false, same, None), + case(18446744073709551615i128, val!(18446744073709551615i128), "1bffffffffffffffff", false, same, None), + case(18446744073709551616u128, val!(18446744073709551616u128), "c249010000000000000000", false, same, None), + case(18446744073709551616i128, val!(18446744073709551616i128), "c249010000000000000000", false, same, None), + case(-18446744073709551617i128, val!(-18446744073709551617i128), "c349010000000000000000", false, same, None), + case(-18446744073709551616i128, val!(-18446744073709551616i128), "3bffffffffffffffff", false, same, None), + case(-1000i16, val!(-1000i16), "3903e7", false, same, None), + case(-1000i32, val!(-1000i32), "3903e7", false, same, None), + case(-1000i64, val!(-1000i64), "3903e7", false, same, None), + case(-1000i128, val!(-1000i128), "3903e7", false, same, None), + case(-100i8, val!(-100i8), "3863", false, same, None), + case(-100i16, val!(-100i16), "3863", false, same, None), + case(-100i32, val!(-100i32), "3863", false, same, None), + case(-100i64, val!(-100i64), "3863", false, same, None), + case(-100i128, val!(-100i128), "3863", false, same, None), + case(-10i8, val!(-10i8), "29", false, same, None), + case(-10i16, val!(-10i16), "29", false, same, None), + case(-10i32, val!(-10i32), "29", false, same, None), + case(-10i64, val!(-10i64), "29", false, same, None), + case(-10i128, val!(-10i128), "29", false, same, None), + case(-1i8, val!(-1i8), "20", false, same, None), + case(-1i16, val!(-1i16), "20", false, same, None), + case(-1i32, val!(-1i32), "20", false, same, None), + case(-1i64, val!(-1i64), "20", false, same, None), + case(-1i128, val!(-1i128), "20", false, same, None), + case(-1i8, val!(-1i8), "3b0000000000000000", true, same, None), + case(-1i16, val!(-1i16), "3b0000000000000000", true, same, None), + case(-1i32, val!(-1i32), "3b0000000000000000", true, same, None), + case(-1i64, val!(-1i64), "3b0000000000000000", true, same, None), + case(-1i128, val!(-1i128), "3b0000000000000000", true, same, None), + case(0.0f32, val!(0.0f32), "f90000", false, Float, None), + case(0.0f64, val!(0.0f64), "f90000", false, Float, None), + case(-0.0f32, val!(-0.0f32), "f98000", false, Float, None), + case(-0.0f64, val!(-0.0f64), "f98000", false, Float, None), + case(1.0f32, val!(1.0f32), "f93c00", false, Float, None), + case(1.0f64, val!(1.0f64), "f93c00", false, Float, None), + case(1.1f32, val!(1.1f32), "fa3f8ccccd", false, Float, None), // Not In RFC + case(1.1f64, val!(1.1f64), "fb3ff199999999999a", false, Float, None), + case(1.5f32, val!(1.5f32), "f93e00", false, Float, None), + case(1.5f64, val!(1.5f64), "f93e00", false, Float, None), + case(65504.0f32, val!(65504.0f32), "f97bff", false, Float, None), + case(65504.0f64, val!(65504.0f64), "f97bff", false, Float, None), + case(100000.0f32, val!(100000.0f32), "fa47c35000", false, Float, None), + case(100000.0f64, val!(100000.0f64), "fa47c35000", false, Float, None), + case(3.4028234663852886e+38f32, val!(3.4028234663852886e+38f32), "fa7f7fffff", false, Float, None), + case(3.4028234663852886e+38f64, val!(3.4028234663852886e+38f64), "fa7f7fffff", false, Float, None), + case(1.0e+300f64, val!(1.0e+300f64), "fb7e37e43c8800759c", false, Float, None), + case(5.960464477539063e-8f32, val!(5.960464477539063e-8f32), "f90001", false, Float, None), + case(5.960464477539063e-8f64, val!(5.960464477539063e-8f64), "f90001", false, Float, None), + case(0.00006103515625f32, val!(0.00006103515625f32), "f90400", false, Float, None), + case(0.00006103515625f64, val!(0.00006103515625f64), "f90400", false, Float, None), + case(-4.0f32, val!(-4.0f32), "f9c400", false, Float, None), + case(-4.0f64, val!(-4.0f64), "f9c400", false, Float, None), + case(-4.1f32, val!(-4.1f32), "fac0833333", false, Float, None), // Not In RFC + case(-4.1f64, val!(-4.1f64), "fbc010666666666666", false, Float, None), + case(core::f32::INFINITY, val!(core::f32::INFINITY), "f97c00", false, Float, None), + case(core::f64::INFINITY, val!(core::f64::INFINITY), "f97c00", false, Float, None), + case(core::f32::INFINITY, val!(core::f32::INFINITY), "fa7f800000", true, Float, None), + case(core::f64::INFINITY, val!(core::f64::INFINITY), "fa7f800000", true, Float, None), + case(core::f32::INFINITY, val!(core::f32::INFINITY), "fb7ff0000000000000", true, Float, None), + case(core::f64::INFINITY, val!(core::f64::INFINITY), "fb7ff0000000000000", true, Float, None), + case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "f9fc00", false, Float, None), + case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "f9fc00", false, Float, None), + case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "faff800000", true, Float, None), + case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "faff800000", true, Float, None), + case(-core::f32::INFINITY, val!(-core::f32::INFINITY), "fbfff0000000000000", true, Float, None), + case(-core::f64::INFINITY, val!(-core::f64::INFINITY), "fbfff0000000000000", true, Float, None), + case(core::f32::NAN, val!(core::f32::NAN), "f97e00", false, Float, None), + case(core::f64::NAN, val!(core::f64::NAN), "f97e00", false, Float, None), + case(core::f32::NAN, val!(core::f32::NAN), "fa7fc00000", true, Float, None), + case(core::f64::NAN, val!(core::f64::NAN), "fa7fc00000", true, Float, None), + case(core::f32::NAN, val!(core::f32::NAN), "fb7ff8000000000000", true, Float, None), + case(core::f64::NAN, val!(core::f64::NAN), "fb7ff8000000000000", true, Float, None), + case(-core::f32::NAN, val!(-core::f32::NAN), "f9fe00", false, Float, None), // Not In RFC + case(-core::f64::NAN, val!(-core::f64::NAN), "f9fe00", false, Float, None), // Not In RFC + case(-core::f32::NAN, val!(-core::f32::NAN), "faffc00000", true, Float, None), // Not In RFC + case(-core::f64::NAN, val!(-core::f64::NAN), "faffc00000", true, Float, None), // Not In RFC + case(-core::f32::NAN, val!(-core::f32::NAN), "fbfff8000000000000", true, Float, None), // Not In RFC + case(-core::f64::NAN, val!(-core::f64::NAN), "fbfff8000000000000", true, Float, None), // Not In RFC + case(false, val!(false), "f4", false, same, None), + case(true, val!(true), "f5", false, same, None), + case(Value::Null, Value::Null, "f6", false, same, None), + case(hex!(""), val!(&b""[..]), "40", false, same, None), + case(hex!("01020304"), val!(&b"\x01\x02\x03\x04"[..]), "4401020304", false, same, None), + case(hex!("0102030405"), val!(&b"\x01\x02\x03\x04\x05"[..]), "5f42010243030405ff", true, same, None), + case("", val!(""), "60", false, ToOwned::to_owned, None), + case("a", val!("a"), "6161", false, ToOwned::to_owned, None), + case('a', val!('a'), "6161", false, same, None), + case("IETF", val!("IETF"), "6449455446", false, ToOwned::to_owned, None), + case("\"\\", val!("\"\\"), "62225c", false, ToOwned::to_owned, None), + case("ü", val!("ü"), "62c3bc", false, ToOwned::to_owned, None), + case('ü', val!('ü'), "62c3bc", false, same, None), + case("水", val!("水"), "63e6b0b4", false, ToOwned::to_owned, None), + case('水', val!('水'), "63e6b0b4", false, same, None), + case("𐅑", val!("𐅑"), "64f0908591", false, ToOwned::to_owned, None), + case('𐅑', val!('𐅑'), "64f0908591", false, same, None), + case("streaming", val!("streaming"), "7f657374726561646d696e67ff", true, ToOwned::to_owned, None), + case(cbor!([]).unwrap(), Vec::::new().into(), "80", false, same, None), + case(cbor!([]).unwrap(), Vec::::new().into(), "9fff", true, same, None), + case(cbor!([1, 2, 3]).unwrap(), cbor!([1, 2, 3]).unwrap(), "83010203", false, same, None), + case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "8301820203820405", false, same, None), + case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "9f018202039f0405ffff", true, same, None), + case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "9f01820203820405ff", true, same, None), + case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "83018202039f0405ff", true, same, None), + case(cbor!([1, [2, 3], [4, 5]]).unwrap(), cbor!([1, [2, 3], [4, 5]]).unwrap(), "83019f0203ff820405", true, same, None), + case((1..=25).collect::>(), (1..=25).map(|x| x.into()).collect::>().into(), "98190102030405060708090a0b0c0d0e0f101112131415161718181819", false, same, None), + case((1..=25).collect::>(), (1..=25).map(|x| x.into()).collect::>().into(), "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff", true, same, None), + case(HashMap::::new(), Value::Map(vec![]), "a0", false, same, None), + case(BTreeMap::::new(), Value::Map(vec![]), "a0", false, same, None), + case(map!{1 => 2, 3 => 4}, cbor!({1 => 2, 3 => 4}).unwrap(), "a201020304", false, same, None), + case(cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), "a26161016162820203", false, same, None), + case(cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), cbor!({"a" => 1, "b" => [2, 3]}).unwrap(), "bf61610161629f0203ffff", true, same, None), + case(cbor!(["a", {"b" => "c"}]).unwrap(), cbor!(["a", {"b" => "c"}]).unwrap(), "826161a161626163", false, same, None), + case(cbor!(["a", {"b" => "c"}]).unwrap(), cbor!(["a", {"b" => "c"}]).unwrap(), "826161bf61626163ff", true, same, None), + case(cbor!({"Fun" => true, "Amt" => -2}).unwrap(), cbor!({"Fun" => true, "Amt" => -2}).unwrap(), "bf6346756ef563416d7421ff", true, same, None), + case(map_big(), vmap_big(), "a56161614161626142616361436164614461656145", false, same, None), + case(Option::::None, Value::Null, "f6", false, same, None), // Not In RFC + case(Option::Some(7u8), val!(7u8), "07", false, same, None), // Not In RFC + case((), Value::Null, "f6", false, same, None), // Not In RFC + case(UnitStruct, Value::Null, "f6", false, same, None), // Not In RFC + case(Newtype(123), val!(123u8), "187b", false, same, None), // Not In RFC + case((22u8, 23u16), cbor!([22, 23]).unwrap(), "821617", false, same, None), // Not In RFC + case(TupleStruct(33, 34), cbor!([33, 34]).unwrap(), "8218211822", false, same, None), // Not In RFC + case(Enum::Unit, cbor!("Unit").unwrap(), "64556e6974", false, same, None), // Not In RFC + case(Enum::Newtype(45), cbor!({"Newtype" => 45}).unwrap(), "a1674e657774797065182d", false, same, None), // Not In RFC + case(Enum::Tuple(56, 67), cbor!({"Tuple" => [56, 67]}).unwrap(), "a1655475706c658218381843", false, same, None), // Not In RFC + case(Enum::Struct { first: 78, second: 89 }, cbor!({ "Struct" => { "first" => 78, "second" => 89 }}).unwrap(), "a166537472756374a2656669727374184e667365636f6e641859", false, same, None), // Not In RFC + case(hex!("0100000000000000000000000000000000000001"), Value::Tag(2, Value::Bytes(hex!("0100000000000000000000000000000000000001").to_vec()).into()), "c2540100000000000000000000000000000000000001", true, same, None), // Not In RFC + case(hex!("0001000000000000000000000000000000000001"), Value::Tag(2, Value::Bytes(hex!("01000000000000000000000000000000000001").to_vec()).into()), "c2540001000000000000000000000000000000000001", true, same, Some(hex!("01000000000000000000000000000000000001"))), // Not In RFC + case(-1i8, val!(-1), "c340", true, same, None), // Not In RFC + case(-1i8, val!(-1), "c35fff", true, same, None), // Not In RFC )] fn codec<'de, T: Serialize + Clone, V: Debug + PartialEq + DeserializeOwned, F: Fn(T) -> V>( input: T, @@ -281,6 +285,7 @@ fn codec<'de, T: Serialize + Clone, V: Debug + PartialEq + DeserializeOwned, F: bytes: &str, alternate: bool, equality: F, + round_trip: Option, ) { let bytes = hex::decode(bytes).unwrap(); @@ -315,7 +320,7 @@ fn codec<'de, T: Serialize + Clone, V: Debug + PartialEq + DeserializeOwned, F: assert!(veq(&value, &decoded)); let decoded: V = value.deserialized().unwrap(); - let answer = equality(input); + let answer = if let Some(rt) = round_trip { rt } else { equality(input) }; eprintln!("{:x?} == {:x?}", answer, decoded); assert_eq!(answer, decoded); } @@ -380,12 +385,6 @@ fn vmap_big() -> Value { ) } -#[inline] -fn bigint() -> Value { - let bytes = hex::decode("0000000000000000000000000000000000000001").unwrap(); - Value::Tag(2, Value::Bytes(bytes).into()) -} - #[derive(Deserialize, Serialize, Copy, Clone, Debug, PartialEq, Eq)] struct UnitStruct;