mod shared;
use shared::assert_streamed_eq;
use data_stream::{FromStream, ToStream, default_settings::PortableSettings};
#[derive(Debug, PartialEq, ToStream, FromStream)]
struct UnitStruct;
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct NewtypeStruct(u32);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct TupleStruct(u32, u64, bool);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct BasicStruct {
x: u32,
y: u64,
z: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct NestedStruct {
inner: BasicStruct,
value: u16,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct OrderedStruct {
#[field(order = 2)]
second: u32,
#[field(order = 0)]
first: u64,
#[field(order = 1)]
middle: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct IgnoredFieldStruct {
kept: u32,
#[field(ignore)]
skipped: u64,
also_kept: bool,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct IgnoredTupleStruct(u32, #[field(ignore)] u64, bool);
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
struct WithString {
name: String,
value: u32,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
struct WithVec {
items: Vec<u32>,
label: String,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum SimpleEnum {
A,
B,
C,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum DataEnum {
Empty,
Single(u32),
Pair(u32, u64),
Named { x: u32, y: bool },
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum CustomIndexEnum {
#[variant(index = 10)]
First,
Second,
#[variant(index = 50)]
Jump,
After,
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
enum EnumWithIgnoredField {
Normal(u32),
WithIgnore {
kept: u32,
#[field(ignore)]
_skipped: bool,
},
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::collections::SizeSettings")]
enum ComplexEnum {
Empty,
WithVec(Vec<u32>),
WithString { name: String, id: u64 },
}
#[derive(Debug, PartialEq, ToStream, FromStream)]
#[stream(bounds = "data_stream::numbers::EndianSettings")]
struct GenericStruct<T: PartialEq + std::fmt::Debug> {
value: T,
flag: bool,
}
#[test]
fn unit_struct() {
assert_streamed_eq::<PortableSettings, _>(&UnitStruct);
}
#[test]
fn newtype_struct() {
assert_streamed_eq::<PortableSettings, _>(&NewtypeStruct(42));
}
#[test]
fn tuple_struct() {
assert_streamed_eq::<PortableSettings, _>(&TupleStruct(1, 2, true));
}
#[test]
fn basic_struct() {
assert_streamed_eq::<PortableSettings, _>(&BasicStruct {
x: 100,
y: 200,
z: false,
});
}
#[test]
fn nested_struct() {
assert_streamed_eq::<PortableSettings, _>(&NestedStruct {
inner: BasicStruct {
x: 1,
y: 2,
z: true,
},
value: 999,
});
}
#[test]
fn ordered_struct() {
assert_streamed_eq::<PortableSettings, _>(&OrderedStruct {
second: 2,
first: 1,
middle: true,
});
}
#[test]
fn ordered_struct_binary_layout() {
use data_stream::to_stream;
let value = OrderedStruct {
second: 2,
first: 1,
middle: true,
};
let mut bytes = Vec::new();
to_stream::<PortableSettings, _, _>(&value, &mut bytes).unwrap();
let mut expected = Vec::new();
to_stream::<PortableSettings, _, _>(&1u64, &mut expected).unwrap();
to_stream::<PortableSettings, _, _>(&true, &mut expected).unwrap();
to_stream::<PortableSettings, _, _>(&2u32, &mut expected).unwrap();
assert_eq!(bytes, expected);
}
#[test]
fn ignored_field_roundtrip() {
let original = IgnoredFieldStruct {
kept: 42,
skipped: 999,
also_kept: true,
};
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: IgnoredFieldStruct =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
assert_eq!(restored.kept, 42);
assert_eq!(restored.skipped, 0);
assert!(restored.also_kept);
}
#[test]
fn ignored_field_smaller_bytes() {
let with_ignore = IgnoredFieldStruct {
kept: 1,
skipped: 0,
also_kept: true,
};
let without_ignore = BasicStruct {
x: 1,
y: 0,
z: true,
};
let mut bytes_ignore = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&with_ignore, &mut bytes_ignore).unwrap();
let mut bytes_full = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&without_ignore, &mut bytes_full).unwrap();
assert!(bytes_ignore.len() < bytes_full.len());
}
#[test]
fn ignored_tuple_field() {
let original = IgnoredTupleStruct(42, 999, true);
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: IgnoredTupleStruct =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
assert_eq!(restored.0, 42);
assert_eq!(restored.1, 0);
assert!(restored.2);
}
#[test]
fn struct_with_string() {
assert_streamed_eq::<PortableSettings, _>(&WithString {
name: "hello".into(),
value: 7,
});
}
#[test]
fn struct_with_vec() {
assert_streamed_eq::<PortableSettings, _>(&WithVec {
items: vec![1, 2, 3],
label: "test".into(),
});
}
#[test]
fn struct_with_empty_collections() {
assert_streamed_eq::<PortableSettings, _>(&WithVec {
items: vec![],
label: String::new(),
});
}
#[test]
fn simple_enum_a() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::A);
}
#[test]
fn simple_enum_b() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::B);
}
#[test]
fn simple_enum_c() {
assert_streamed_eq::<PortableSettings, _>(&SimpleEnum::C);
}
#[test]
fn data_enum_empty() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Empty);
}
#[test]
fn data_enum_single() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Single(42));
}
#[test]
fn data_enum_pair() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Pair(1, 2));
}
#[test]
fn data_enum_named() {
assert_streamed_eq::<PortableSettings, _>(&DataEnum::Named { x: 10, y: true });
}
#[test]
fn custom_index_first() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::First);
}
#[test]
fn custom_index_second() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::Second);
}
#[test]
fn custom_index_jump() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::Jump);
}
#[test]
fn custom_index_after() {
assert_streamed_eq::<PortableSettings, _>(&CustomIndexEnum::After);
}
#[test]
fn custom_index_binary_values() {
use data_stream::to_stream;
let mut bytes_first = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::First, &mut bytes_first).unwrap();
let mut bytes_second = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::Second, &mut bytes_second).unwrap();
let mut bytes_jump = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::Jump, &mut bytes_jump).unwrap();
let mut bytes_after = Vec::new();
to_stream::<PortableSettings, _, _>(&CustomIndexEnum::After, &mut bytes_after).unwrap();
let read_disc = |bytes: &[u8]| -> u32 {
data_stream::from_stream::<PortableSettings, u32, _>(&mut &bytes[..]).unwrap()
};
assert_eq!(read_disc(&bytes_first), 10);
assert_eq!(read_disc(&bytes_second), 11);
assert_eq!(read_disc(&bytes_jump), 50);
assert_eq!(read_disc(&bytes_after), 51);
}
#[test]
fn enum_ignored_field() {
let original = EnumWithIgnoredField::WithIgnore {
kept: 42,
_skipped: true,
};
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&original, &mut bytes).unwrap();
let restored: EnumWithIgnoredField =
data_stream::from_stream::<PortableSettings, _, _>(&mut &bytes[..]).unwrap();
match restored {
EnumWithIgnoredField::WithIgnore {
kept,
_skipped: skipped,
} => {
assert_eq!(kept, 42);
assert!(!skipped);
}
EnumWithIgnoredField::Normal(_) => panic!("wrong variant"),
}
}
#[test]
fn complex_enum_empty() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::Empty);
}
#[test]
fn complex_enum_with_vec() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::WithVec(vec![1, 2, 3]));
}
#[test]
fn complex_enum_with_string() {
assert_streamed_eq::<PortableSettings, _>(&ComplexEnum::WithString {
name: "test".into(),
id: 42,
});
}
#[test]
fn generic_struct_u32() {
assert_streamed_eq::<PortableSettings, _>(&GenericStruct {
value: 42u32,
flag: true,
});
}
#[test]
fn generic_struct_bool() {
assert_streamed_eq::<PortableSettings, _>(&GenericStruct {
value: false,
flag: true,
});
}
#[test]
fn invalid_enum_discriminant() {
let mut bytes = Vec::new();
data_stream::to_stream::<PortableSettings, _, _>(&999u32, &mut bytes).unwrap();
let result = data_stream::from_stream::<PortableSettings, SimpleEnum, _>(&mut &bytes[..]);
assert!(result.is_err());
}
#[test]
fn read_from_empty_stream() {
let bytes: &[u8] = &[];
let result = data_stream::from_stream::<PortableSettings, BasicStruct, _>(&mut &bytes[..]);
assert!(result.is_err());
}
#[test]
fn read_enum_from_empty_stream() {
let bytes: &[u8] = &[];
let result = data_stream::from_stream::<PortableSettings, SimpleEnum, _>(&mut &bytes[..]);
assert!(result.is_err());
}