use cbor_tools::{ByteString, CborType, Encode, Float, Indefinite, Integer, Tag, TextString};
use half::f16;
use hex_literal::hex;
use std::convert::TryFrom;
#[test]
fn special_types() {
assert_eq!(CborType::Bool(false).encode(), hex!("F4"));
assert_eq!(CborType::Bool(true).encode(), hex!("F5"));
assert_eq!(CborType::Null.encode(), hex!("F6"));
assert_eq!(CborType::Undefined.encode(), hex!("F7"));
}
#[test]
fn text_strings() {
assert_eq!(CborType::from("").encode(), hex!("60"));
assert_eq!(CborType::from("a").encode(), hex!("61 61"));
assert_eq!(CborType::from("IETF").encode(), hex!("64 49455446"));
assert_eq!(CborType::from("\"\\").encode(), hex!("62 225c"));
assert_eq!(CborType::from("\u{00fc}").encode(), hex!("62 c3bc"));
assert_eq!(CborType::from("\u{6c34}").encode(), hex!("63e6b0b4"));
let s = String::from("12345678").repeat(32);
assert_eq!(s.len(), 256);
let buf = CborType::from(&s[..]).encode();
assert_eq!(&buf[..3], hex!("79 0100"));
assert_eq!(buf.len(), 259);
for chunk in buf[3..].chunks(8) {
assert_eq!(chunk, "12345678".as_bytes());
}
let s = String::from("12345678").repeat(8192);
assert_eq!(s.len(), 65536);
let buf = CborType::from(&s[..]).encode();
assert_eq!(buf.len(), 65541);
assert_eq!(&buf[..5], hex!("7a 00 01 00 00"));
let list = vec!["strea", "ming"];
let list = list.into_iter().map(|s| TextString::from(s)).collect();
let data = CborType::Indefinite(Indefinite::TextString(list));
assert_eq!(data.encode(), hex!("7f 65 7374726561 64 6d696e67 ff"));
}
#[test]
fn byte_strings() {
assert_eq!(CborType::from(&b""[..]).encode(), hex!("40"));
assert_eq!(
CborType::from(&b"\x01\x02\x03\x04"[..]).encode(),
hex!("4401020304")
);
let v: Vec<u8> = (1..9).into_iter().collect::<Vec<u8>>().repeat(32);
assert_eq!(v.len(), 256);
let buf = CborType::from(&v[..]).encode();
assert_eq!(&buf[..3], hex!("59 0100"));
assert_eq!(buf.len(), 259);
for chunk in buf[3..].chunks(8) {
assert_eq!(chunk, b"\x01\x02\x03\x04\x05\x06\x07\x08");
}
let list = vec![vec![1u8, 2], vec![3u8, 4, 5]];
let list = list.into_iter().map(|x| ByteString::from(x)).collect();
let data = CborType::Indefinite(Indefinite::ByteString(list));
assert_eq!(data.encode(), hex!("5f 42 0102 43 030405 ff"));
let str1 = Vec::from(&b"\xaa\xbb\xcc\xdd"[..]);
let str2 = Vec::from(&b"\xee\xff\x99"[..]);
let list = vec![str1, str2];
let list = list.into_iter().map(|x| ByteString::from(x)).collect();
let data = CborType::Indefinite(Indefinite::ByteString(list));
assert_eq!(data.encode(), hex!("5f 44 aabbccdd 43 eeff99 ff"));
}
#[test]
fn uint() {
assert_eq!(CborType::from(0u8).encode(), hex!("00"));
assert_eq!(CborType::from(1u8).encode(), hex!("01"));
assert_eq!(CborType::from(10u8).encode(), hex!("0a"));
assert_eq!(CborType::from(23u8).encode(), hex!("17"));
assert_eq!(CborType::from(24u8).encode(), hex!("18 18"));
assert_eq!(CborType::from(25u8).encode(), hex!("18 19"));
assert_eq!(CborType::from(100u8).encode(), hex!("18 64"));
assert_eq!(CborType::from(1000u16).encode(), hex!("19 03e8"));
assert_eq!(CborType::from(1000000u32).encode(), hex!("1a 000f 4240"));
assert_eq!(
CborType::from(1000000000000u64).encode(),
hex!("1b 0000 00e8 d4a5 1000")
);
assert_eq!(
CborType::from(18446744073709551615u64).encode(),
hex!("1b ffff ffff ffff ffff")
);
assert_eq!(CborType::from(255_u16).encode(), hex!("18 ff"));
assert_eq!(CborType::from(256_u16).encode(), hex!("19 0100"));
assert_eq!(CborType::from(65535_u32).encode(), hex!("19 ffff"));
assert_eq!(CborType::from(65536_u32).encode(), hex!("1a 0001 0000"));
assert_eq!(
CborType::from((1_u64 << 32) - 1).encode(),
hex!("1a ffff ffff")
);
assert_eq!(
CborType::from(1_u64 << 32).encode(),
hex!("1b 0000 0001 0000 0000")
);
assert_eq!(CborType::from(100u16).encode(), hex!("18 64"));
assert_eq!(CborType::from(100u32).encode(), hex!("18 64"));
assert_eq!(CborType::from(100u64).encode(), hex!("18 64"));
let i = Integer::U32(100);
assert_eq!(CborType::from(i).encode(), hex!("1a 0000 0064"));
}
#[test]
fn nint() {
assert_eq!(CborType::from(0_i8).encode(), hex!("00"));
assert_eq!(CborType::from(-1_i8).encode(), hex!("20"));
assert_eq!(CborType::from(-10_i8).encode(), hex!("29"));
assert_eq!(CborType::from(-100_i8).encode(), hex!("38 63"));
assert_eq!(CborType::from(-1000_i16).encode(), hex!("39 03e7"));
assert_eq!(CborType::from(-24_i8).encode(), hex!("37"));
assert_eq!(CborType::from(-25_i8).encode(), hex!("38 18"));
assert_eq!(CborType::from(-256_i16).encode(), hex!("38 ff"));
assert_eq!(CborType::from(-257_i16).encode(), hex!("39 0100"));
assert_eq!(CborType::from(-65536_i32).encode(), hex!("39 ffff"));
assert_eq!(CborType::from(-65537_i32).encode(), hex!("3a 0001 0000"));
assert_eq!(CborType::from(-1_i64 << 32).encode(), hex!("3a ffff ffff"));
assert_eq!(
CborType::from((-1_i64 << 32) - 1).encode(),
hex!("3b 0000 0001 0000 0000")
);
let val = Integer::try_from(-18446744073709551616_i128).unwrap();
assert_eq!(CborType::from(val).encode(), hex!("3b ffff ffff ffff ffff"));
Integer::try_from((u64::MAX as i128) + 1).unwrap_err();
Integer::try_from(-2 - (u64::MAX as i128)).unwrap_err();
}
#[test]
fn int_debug() {
let s = format!("{:?}", Integer::from(0));
assert_eq!(s, "Integer { U5: 0 }");
let s = format!("{:?}", Integer::from(23));
assert_eq!(s, "Integer { U5: 23 }");
let s = format!("{:?}", Integer::from(24));
assert_eq!(s, "Integer { U8: 24 }");
let s = format!("{:?}", Integer::from(256));
assert_eq!(s, "Integer { U16: 256 }");
let s = format!("{:?}", Integer::from(65536));
assert_eq!(s, "Integer { U32: 65536 }");
let s = format!("{:?}", Integer::from(1000000000000u64));
assert_eq!(s, "Integer { U64: 1000000000000 }");
let s = format!("{:?}", Integer::from(-1));
assert_eq!(s, "Integer { N5: -1 }");
let s = format!("{:?}", Integer::from(-24));
assert_eq!(s, "Integer { N5: -24 }");
let s = format!("{:?}", Integer::from(-25));
assert_eq!(s, "Integer { N8: -25 }");
let s = format!("{:?}", Integer::from(-256));
assert_eq!(s, "Integer { N8: -256 }");
let s = format!("{:?}", Integer::from(-257));
assert_eq!(s, "Integer { N16: -257 }");
let s = format!("{:?}", Integer::from(-65536));
assert_eq!(s, "Integer { N16: -65536 }");
let s = format!("{:?}", Integer::from(-65537));
assert_eq!(s, "Integer { N32: -65537 }");
let s = format!("{:?}", Integer::from(-1i64 << 32));
assert_eq!(s, "Integer { N32: -4294967296 }");
let s = format!("{:?}", Integer::from((-1i64 << 32) - 1));
assert_eq!(s, "Integer { N64: -4294967297 }");
let s = format!("{:?}", Integer::from(-1000000000000i64));
assert_eq!(s, "Integer { N64: -1000000000000 }");
let s = format!("{:?}", Integer::try_from(-(u64::MAX as i128)).unwrap());
assert_eq!(s, "Integer { N64: -18446744073709551615 }");
}
fn make_indef_array<T>(list: Vec<T>) -> CborType
where
T: Into<CborType>,
{
let regular_array = CborType::from(list);
if let CborType::Array(a) = regular_array {
CborType::Indefinite(Indefinite::Array(a))
} else {
unreachable!()
}
}
#[test]
fn arrays() {
let empty = Vec::<u32>::new();
assert_eq!(CborType::from(empty.clone()).encode(), hex!("80"));
let nums = vec![1, 2, 3];
assert_eq!(CborType::from(nums).encode(), hex!("83 010203"));
let deep = vec![
CborType::from(1),
CborType::from(vec![2, 3]),
CborType::from(vec![4, 5]),
];
assert_eq!(
CborType::from(deep.clone()).encode(),
hex!("8301820203820405")
);
let twentyfive: Vec<u32> = (1..26).into_iter().collect();
let expected = hex!("98190102030405060708090a0b0c0d0e0f101112131415161718181819");
assert_eq!(CborType::from(twentyfive.clone()).encode(), expected);
assert_eq!(make_indef_array(empty).encode(), hex!("9fff"));
assert_eq!(make_indef_array(deep).encode(), hex!("9f01820203820405ff"));
let deep2 = vec![
CborType::from(1),
CborType::from(vec![2, 3]),
make_indef_array(vec![4, 5]),
];
assert_eq!(
make_indef_array(deep2).encode(),
hex!("9f018202039f0405ffff")
);
let deep3 = vec![
CborType::from(1),
CborType::from(vec![2, 3]),
make_indef_array(vec![4, 5]),
];
assert_eq!(CborType::from(deep3).encode(), hex!("83018202039f0405ff"));
let deep4 = vec![
CborType::from(1),
make_indef_array(vec![2, 3]),
CborType::from(vec![4, 5]),
];
assert_eq!(CborType::from(deep4).encode(), hex!("83019f0203ff820405"));
let expected = hex!("9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff");
assert_eq!(make_indef_array(twentyfive).encode(), expected);
}
fn make_indef_map<K, V>(list: Vec<(K, V)>) -> CborType
where
K: Into<CborType>,
V: Into<CborType>,
{
let regular_map = CborType::from(list);
if let CborType::Map(m) = regular_map {
CborType::Indefinite(Indefinite::Map(m))
} else {
unreachable!()
}
}
#[test]
fn maps() {
let empty = Vec::<(i8, i8)>::new();
assert_eq!(CborType::from(empty).encode(), hex!("a0"));
let kv = vec![(1, 2), (3, 4)];
assert_eq!(CborType::from(kv).encode(), hex!("a2 0102 0304"));
let kv = vec![
(CborType::from("a"), CborType::from(1)),
(CborType::from("b"), CborType::from(vec![2, 3])),
];
assert_eq!(CborType::from(kv).encode(), hex!("a2 6161 01 6162 820203"));
let kv = vec![("a", "A"), ("b", "B"), ("c", "C"), ("d", "D"), ("e", "E")];
let expected = hex!("a56161614161626142616361436164614461656145");
assert_eq!(CborType::from(kv).encode(), expected);
let kv = vec![
(CborType::from("a"), CborType::from(1)),
(CborType::from("b"), make_indef_array(vec![2, 3])),
];
assert_eq!(make_indef_map(kv).encode(), hex!("bf61610161629f0203ffff"));
}
#[test]
fn floats() {
assert_eq!(CborType::from(0.0).encode(), hex!("f9 0000"));
assert_eq!(CborType::from(-0.0).encode(), hex!("f9 8000"));
assert_eq!(CborType::from(1.0).encode(), hex!("f9 3c00"));
assert_eq!(CborType::from(1.1f64).encode(), hex!("fb3ff199999999999a"));
assert_eq!(CborType::from(1.5).encode(), hex!("f93e00"));
assert_eq!(CborType::from(65504.0).encode(), hex!("f97bff"));
assert_eq!(CborType::from(100000.0).encode(), hex!("fa47c35000"));
assert_eq!(
CborType::from(3.4028234663852886e+38).encode(),
hex!("fa7f7fffff")
);
assert_eq!(
CborType::from(1.0e+300).encode(),
hex!("fb7e37e43c8800759c")
);
assert_eq!(
CborType::from(5.960464477539063e-8).encode(),
hex!("f90001")
);
assert_eq!(CborType::from(0.00006103515625).encode(), hex!("f90400"));
assert_eq!(CborType::from(-4.0).encode(), hex!("f9c400"));
assert_eq!(CborType::from(-4.1).encode(), hex!("fbc010666666666666"));
assert_eq!(CborType::from(f16::INFINITY).encode(), hex!("f97c00"));
assert_eq!(CborType::from(f16::NAN).encode(), hex!("f97e00"));
assert_eq!(CborType::from(f16::NEG_INFINITY).encode(), hex!("f9fc00"));
assert_eq!(
CborType::Float(Float::F32(f32::INFINITY)).encode(),
hex!("fa7f800000")
);
assert_eq!(
CborType::Float(Float::F32(f32::NAN)).encode(),
hex!("fa7fc00000")
);
assert_eq!(
CborType::Float(Float::F32(f32::NEG_INFINITY)).encode(),
hex!("faff800000")
);
assert_eq!(
CborType::Float(Float::F64(f64::INFINITY)).encode(),
hex!("fb7ff0000000000000")
);
assert_eq!(
CborType::Float(Float::F64(f64::NAN)).encode(),
hex!("fb7ff8000000000000")
);
assert_eq!(
CborType::Float(Float::F64(f64::NEG_INFINITY)).encode(),
hex!("fbfff0000000000000")
);
assert_eq!(
CborType::Float(Float::F32(1.5)).encode(),
hex!("fa3fc00000")
);
assert_eq!(
CborType::Float(Float::F64(1.5)).encode(),
hex!("fb3ff8000000000000")
);
}
#[test]
fn tags() {
let bytestring = CborType::from(&[0u8; 12][..]);
let tagged = CborType::Tagged(Tag::POS_BIGNUM.wrap(bytestring));
assert_eq!(tagged.encode(), hex!("c2 4c 000000000000000000000000"));
}
#[test]
fn map_from() {
let kv_list = vec![(123, "foo"), (456, "bar")];
let map = CborType::from(kv_list);
let cbor_bytes = map.encode();
eprintln!("{:x?}", cbor_bytes);
assert_eq!(cbor_bytes, hex!("a2 18 7b 63 666f6f 19 01c8 63 626172"));
}
#[test]
fn array_from() {
let list = vec![CborType::from("abc"), CborType::from(123)];
let cbor_tree = CborType::from(list);
let cbor_bytes = cbor_tree.encode();
eprintln!("{:x?}", cbor_bytes);
assert_eq!(cbor_bytes, hex!("82 63 616263 18 7b"));
}