#![cfg(all(feature = "serde1", feature = "use_std"))]
use std::{ io, fmt };
use std::collections::BTreeMap;
use serde::{ Serialize, Deserialize };
use cbor4ii::core::dec;
use cbor4ii::serde::{ to_vec, from_slice };
#[track_caller]
fn de<'a,T>(bytes: &'a [u8], _value: &T)
-> T
where T: Deserialize<'a>
{
match from_slice(bytes) {
Ok(t) => t,
Err(err) => panic!("{:?}: {:?}", err, bytes)
}
}
macro_rules! assert_test {
( $value:expr ) => {{
let buf = to_vec(Vec::new(), &$value).unwrap();
let value = de(&buf, &$value);
assert_eq!(value, $value, "{:?}", buf);
}}
}
#[test]
fn test_serialize_compat() {
let value = vec![
Some(0x99u32),
None,
Some(0x33u32)
];
assert_test!(value);
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
enum Enum {
Unit,
NewType(i32),
Tuple(String, bool),
Struct { x: i32, y: i32 },
}
assert_test!(Enum::Unit);
assert_test!(Enum::NewType(0x999));
assert_test!(Enum::Tuple("123".into(), false));
assert_test!(Enum::Struct { x: 0x99, y: -0x99 });
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
#[serde(untagged)]
enum UntaggedEnum {
Bar(i32),
Foo(Box<str>)
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct NewType<T>(T);
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Test<'a> {
name: char,
test: TestMap,
#[serde(with = "serde_bytes")]
bytes: Vec<u8>,
#[serde(with = "serde_bytes")]
bytes2: Vec<u8>,
map: BTreeMap<String, Enum>,
untag: (UntaggedEnum, UntaggedEnum),
new: NewType<UntaggedEnum>,
some: Option<()>,
str_ref: &'a str
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct TestMap(BTreeMap<TestObj, BoxSet>);
#[derive(Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd, Debug)]
struct TestObj(String);
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct BoxSet(Vec<TestObj>);
let test = Test {
name: 'G',
test: TestMap({
let mut map = BTreeMap::new();
map.insert(TestObj("obj".into()), BoxSet(Vec::new()));
map.insert(TestObj("obj2".into()), BoxSet(vec![
TestObj("obj3".into()),
TestObj("obj4".into()),
TestObj(String::new())
]));
map
}),
bytes: Vec::from("bbbbbbbbbbb".as_bytes()),
bytes2: Vec::new(),
map: {
let mut map = BTreeMap::new();
map.insert("key0".into(), Enum::Unit);
map.insert("key1".into(), Enum::Tuple("value".into(), true));
map.insert("key2".into(), Enum::Struct {
x: -1,
y: 0x123
});
map.insert("key3".into(), Enum::NewType(-999));
map
},
untag: (UntaggedEnum::Foo("a".into()), UntaggedEnum::Bar(0)),
new: NewType(UntaggedEnum::Foo("???".into())),
some: Some(()),
str_ref: "hello world"
};
assert_test!(test);
assert_test!(Some(10u32));
assert_test!(Some(vec![(10u128, 99999i128)]));
}
#[test]
fn test_serde_enum_flatten() {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Deserialize, Serialize)]
pub enum Platform {
Amd64,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Package {
#[serde(flatten)]
pub flattened: Flattened,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Flattened {
pub platform: Platform
}
let pkg = Package {
flattened: Flattened {
platform: Platform::Amd64,
},
};
let pkgs = vec![pkg];
assert_test!(pkgs);
}
#[test]
fn test_serde_value() {
use cbor4ii::core::Value;
assert_test!(Value::Map(vec![(
Value::Text("a".into()),
Value::Bool(false)
)]));
assert_test!(Value::Integer(u64::MAX as i128 + 99));
}
#[test]
fn test_serde_cow() {
use std::borrow::Cow;
use std::convert::Infallible;
struct SlowReader<'de>(&'de [u8]);
impl<'de> dec::Read<'de> for SlowReader<'de> {
type Error = Infallible;
#[inline]
fn fill<'b>(&'b mut self, _want: usize) -> Result<dec::Reference<'de, 'b>, Self::Error> {
Ok(if self.0.is_empty() {
dec::Reference::Long(self.0)
} else {
dec::Reference::Long(&self.0[..1])
})
}
#[inline]
fn advance(&mut self, n: usize) {
let len = core::cmp::min(self.0.len(), n);
self.0 = &self.0[len..];
}
}
pub fn short_from_slice<'a, T>(buf: &'a [u8])
-> Result<T, cbor4ii::serde::DecodeError<Infallible>>
where
T: serde::Deserialize<'a>,
{
let reader = SlowReader(buf);
let mut deserializer = cbor4ii::serde::Deserializer::new(reader);
serde::Deserialize::deserialize(&mut deserializer)
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(untagged)]
enum CowStr<'a> {
#[serde(borrow)]
Borrowed(&'a str),
Owned(String)
}
impl CowStr<'_> {
fn as_ref(&self) -> &str {
match self {
CowStr::Borrowed(v) => v,
CowStr::Owned(v) => v.as_str()
}
}
}
assert_test!(Cow::Borrowed("123"));
assert_test!(CowStr::Borrowed("321"));
let input = "1234567";
let buf = to_vec(Vec::new(), &input).unwrap();
let value: CowStr = from_slice(&buf).unwrap();
if let CowStr::Borrowed(s) = value {
assert_eq!(input, s);
} else {
panic!()
}
let value: CowStr = short_from_slice(&buf).unwrap();
assert_eq!(input, value.as_ref(), "{:?}", buf);
let value: Cow<str> = short_from_slice(&buf).unwrap();
assert_eq!(input, value.as_ref(), "{:?}", buf);
}
#[test]
fn test_serde_skip() {
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct SkipIt {
a: Option<u8>,
#[serde(skip_deserializing)]
b: Option<u8>,
c: Option<u8>
}
let skipit = SkipIt {
a: Some(0x1),
b: Some(0xff),
c: Some(0xfb)
};
let buf = to_vec(Vec::new(), &skipit).unwrap();
let value = de(&buf, &skipit);
assert_eq!(value.a, skipit.a);
assert_eq!(value.b, None);
assert_eq!(value.c, skipit.c);
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Full {
a: u32,
b: String,
c: Vec<u64>,
d: Option<Box<Full>>,
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Missing1 {
a: u32,
b: String,
c: Vec<u64>,
}
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
struct Missing2 {
a: u32,
b: String,
d: Option<Box<Full>>
}
let input = Full {
a: u32::MAX,
b: String::from("short"),
c: vec![0x1, 0x2, 0x3, u64::MAX],
d: Some(Box::new(Full {
a: 0x42,
b: String::new(),
c: vec![u32::MAX.into()],
d: None
}))
};
let buf = to_vec(Vec::new(), &input).unwrap();
let value: Missing1 = from_slice(&buf).unwrap();
assert_eq!(value.a, input.a);
assert_eq!(value.b, input.b);
assert_eq!(value.c, input.c);
let value: Missing2 = from_slice(&buf).unwrap();
assert_eq!(value.a, input.a);
assert_eq!(value.b, input.b);
assert_eq!(value.d, input.d);
}
#[test]
fn test_serde_format_args() {
struct Args<T>(T);
impl<T: fmt::Debug> Serialize for Args<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.collect_str(&format_args!("{:?}", self.0))
}
}
{
let args = Args((1u32, 2u64, "123"));
let buf = to_vec(Vec::new(), &args).unwrap();
let output: &str = from_slice(&buf).unwrap();
assert!(buf.len() <= 256);
assert_eq!(output, format!("{:?}", args.0))
}
{
let args = Args(vec![
String::from("123"),
std::iter::repeat('*').take(1024).collect(),
std::iter::repeat('#').take(32).collect(),
String::new(),
String::from("321")
]);
let buf = to_vec(Vec::new(), &args).unwrap();
let output: String = from_slice(&buf).unwrap();
assert!(buf.len() > 256);
assert_eq!(output, format!("{:?}", args.0))
}
{
struct BadDebug;
impl fmt::Debug for BadDebug {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
Err(fmt::Error)
}
}
let args = Args(BadDebug);
assert!(to_vec(Vec::new(), &args).is_err());
}
{
struct BadWriter;
impl io::Write for BadWriter {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "bad writer"))
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
let args = Args(1);
let mut writer = BadWriter;
let err = cbor4ii::serde::to_writer(&mut writer, &args).unwrap_err();
let err = match err {
cbor4ii::serde::EncodeError::Core(cbor4ii::core::error::EncodeError::Write(err)) => err,
_ => panic!()
};
assert_eq!(err.kind(), io::ErrorKind::Other);
}
}
#[test]
fn test_serde_any_u128() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(untagged)]
enum AnyU128 {
U128(u128),
Str(String)
}
let input = AnyU128::U128(u64::MAX as u128 + 99);
let buf = to_vec(Vec::new(), &input).unwrap();
{
let value: AnyU128 = serde_cbor::from_slice(&buf).unwrap();
assert_ne!(input, value);
assert_eq!(value, AnyU128::Str("\u{1}\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}b".into()))
}
assert!(from_slice::<AnyU128>(&buf).is_err())
}
#[test]
fn test_serde_regression_issue4() {
#[derive(Deserialize, Serialize, Debug, PartialEq)]
enum Foo {
A(String),
}
let foo = Foo::A(String::new());
let mut data = Vec::new();
cbor4ii::serde::to_writer(&mut data, &foo).unwrap();
let reader = std::io::BufReader::new(data.as_slice());
let foo2: Foo = cbor4ii::serde::from_reader(reader).unwrap();
assert_eq!(foo, foo2);
}
#[test]
fn test_serde_regression_issue6() {
let val = cbor4ii::core::Value::Null;
let ret = cbor4ii::serde::to_vec(vec![], &val).unwrap();
assert_eq!(ret, vec![0xf6]);
}
#[test]
fn test_serde_regression_any_f64() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[serde(untagged)]
enum AnyF64 {
F64(f64),
Str(String)
}
let anyf64 = AnyF64::F64(99.);
let buf = to_vec(Vec::new(), &anyf64).unwrap();
assert_eq!(anyf64, de(&buf, &anyf64));
}
#[test]
fn test_serde_ignore_any_simple() {
#[derive(Serialize, Debug, PartialEq)]
struct Bar {
a: f64,
b: f64,
c: bool
}
#[derive(Deserialize, Debug, PartialEq)]
struct Baz {
b: f64,
c: bool
}
let bar = Bar {
a: 1.,
b: 2.,
c: true
};
let bar_bytes = to_vec(Vec::new(), &bar).unwrap();
let baz: Baz = from_slice(&bar_bytes).unwrap();
assert_eq!(bar.b, baz.b);
assert_eq!(bar.c, baz.c);
}
#[test]
fn test_regression_min_i64() {
let buf = to_vec(Vec::new(), &i64::MIN).unwrap();
let min_i64: i64 = from_slice(&buf).unwrap();
assert_eq!(min_i64, i64::MIN);
}
#[test]
fn test_display_ser_len() {
struct Test {
long: char,
short: char
}
impl fmt::Display for Test {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = (0..257).map(|_| self.long).collect::<String>();
write!(f, "{}", s)?;
for _ in 0..257 {
write!(f, "{}", self.short)?;
}
Ok(())
}
}
impl Serialize for Test {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.collect_str(self)
}
}
let test = Test {
long: 'l',
short: 's'
};
let buf = to_vec(Vec::new(), &test).unwrap();
assert!(dbg!(buf.len()) < 777); assert!(dbg!(buf.len()) <= 523);
}
#[cfg(feature = "half-f16")]
#[test]
fn test_regression_f16() {
use cbor4ii::core::Value;
use cbor4ii::core::enc::Encode;
use cbor4ii::core::utils::BufWriter;
let mut buf = BufWriter::new(Vec::new());
half::f16::from_f32(12.).encode(&mut buf).unwrap();
let value: Value = from_slice(buf.buffer()).unwrap();
match value {
Value::Float(v) => assert_eq!(v, 12.),
_ => panic!()
}
}