mod common;
use common::*;
use core::ops::Deref;
use xdrs::{ReadResult, ReadXDR, Reader, WriteXDR, read_xdr};
#[cfg(feature = "repr")]
mod xdr_field_rename {
use xdrs::xdr_repr::*;
#[test]
fn struct_field_xdr_name_honored() {
#[allow(dead_code)]
#[derive(xdrs::XDR)]
struct Packet {
#[xdr(name = "wire_count")]
rust_count: u32,
}
let type_def = <Packet as HasTypeDef>::type_def();
let formatted = Definition::Type(type_def.clone()).to_string();
let TypeDef::Struct(_, body) = &type_def else {
panic!("derive should emit a struct type definition");
};
let fields = body.fields();
assert_eq!(fields.len(), 1);
let Declaration::Named { name, .. } = &fields[0] else {
panic!("expected a named declaration");
};
assert_eq!(name.0, "wire_count");
assert!(formatted.contains("unsigned int wire_count;"));
assert!(!formatted.contains("rust_count"));
}
#[test]
fn struct_field_without_rename_uses_rust_name() {
#[allow(dead_code)]
#[derive(xdrs::XDR)]
struct Packet {
count: u32,
}
let type_def = <Packet as HasTypeDef>::type_def();
let formatted = Definition::Type(type_def).to_string();
assert!(formatted.contains("unsigned int count;"));
}
}
#[test]
fn struct_foo() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Foo {
bytes: [u8; 3],
blerg: i32,
}
let val: Foo = Foo {
bytes: [0xAA, 0xBB, 0xCC],
blerg: 7,
};
let expected = &hex!("aabbcc07");
CXS::check_codec(&val, expected);
let expected = &hex!("aabbcc0000000007");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_boo() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Boo<'a> {
blerg: i32,
bytes: &'a [u8; 9],
}
let bytes = [7u8; 9];
let val = Boo {
blerg: -5,
bytes: &bytes,
};
let expected = &hex!("3a070707070707070707");
CXS::check_codec(&val, expected);
let expected = &hex!("fffffffb070707070707070707000000");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_unit() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Unity();
let val = Unity();
CXS::check_codec(&val, b"");
TXS::check_codec(&val, b"");
}
#[test]
fn struct_bare() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Bare;
let val = Bare;
CXS::check_codec(&val, b"");
TXS::check_codec(&val, b"");
}
#[test]
fn newtype() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct New<'a>(&'a [u8; 6]);
let bytes = [0, 1, 2, 3, 4, 5];
let val = New(&bytes);
let expected = &hex!("000102030405");
CXS::check_codec(&val, expected);
let expected = &hex!("0001020304050000");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_into_from_type() {
#[derive(Debug, Clone, PartialEq, Eq, ReadXDR, WriteXDR)]
#[xdr(into_type = "u32", from_type = "u32")]
struct U32(u8);
impl Into<u32> for U32 {
fn into(self) -> u32 {
self.0.into()
}
}
impl From<u32> for U32 {
fn from(n: u32) -> Self {
Self(n.try_into().unwrap())
}
}
let val = U32(7);
let expected = &hex!("07");
CXS::check_codec(&val, expected);
let expected = &hex!("00000007");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_via_type() {
#[derive(Debug, Clone, PartialEq, Eq, ReadXDR, WriteXDR)]
#[xdr(via = "u32")]
struct U32(u8);
impl Into<u32> for U32 {
fn into(self) -> u32 {
self.0.into()
}
}
impl From<u32> for U32 {
fn from(n: u32) -> Self {
Self(n.try_into().unwrap())
}
}
let val = U32(7);
let expected = &hex!("07");
CXS::check_codec(&val, expected);
let expected = &hex!("00000007");
TXS::check_codec(&val, expected);
}
#[test]
fn field_into_from_type() {
#[derive(Debug, Clone, PartialEq, Eq)]
struct U32(u32);
impl From<u32> for U32 {
fn from(n: u32) -> Self {
Self(n)
}
}
impl Into<u32> for U32 {
fn into(self) -> u32 {
self.0
}
}
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Container {
#[xdr(into_type = "u32", from_type = "u32")]
item: U32,
}
let val = Container { item: U32(7) };
let expected = &hex!("07");
CXS::check_codec(&val, expected);
let expected = &hex!("00000007");
TXS::check_codec(&val, expected);
}
#[test]
fn field_via_type() {
#[derive(Debug, Clone, PartialEq, Eq)]
struct U32(u32);
impl From<u32> for U32 {
fn from(n: u32) -> Self {
Self(n)
}
}
impl Into<u32> for U32 {
fn into(self) -> u32 {
self.0
}
}
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Container {
#[xdr(via = "u32")]
item: U32,
}
let val = Container { item: U32(7) };
let expected = &hex!("07");
CXS::check_codec(&val, expected);
let expected = &hex!("00000007");
TXS::check_codec(&val, expected);
}
#[test]
fn ref_newtype() {
#[derive(Debug, PartialEq, Eq, WriteXDR)]
#[repr(transparent)]
struct Buf([u8; 3]);
impl Deref for Buf {
type Target = [u8; 3];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> From<&'a [u8; 3]> for &'a Buf {
fn from(arr: &[u8; 3]) -> Self {
let ptr = arr as *const [u8; 3] as *const Buf;
unsafe { &*ptr }
}
}
impl<'r: 'a, 'a> ReadXDR<'r> for &'a Buf {
fn read_xdr<R: Reader<'r>>(r: &mut R) -> ReadResult<Self> {
let arr: &[u8; 3] = read_xdr(r)?;
let val = Self::from(arr);
Ok(val)
}
}
let arr = [0, 1, 2];
let buf = Buf(arr);
CXS::check_codec(&&buf, &hex!("000102"));
TXS::check_codec(&&buf, &hex!("00010200"));
let expected = hex!("000102");
let buf2: &Buf = xdrs::cxs::decode(&expected).unwrap();
assert_eq!(&buf2.0, &arr);
}
#[test]
fn phantom_data() {
#[derive(Debug, PartialEq, Eq)]
struct Erik;
#[derive(Debug, PartialEq, Eq, ReadXDR, WriteXDR)]
struct Opera<T> {
phantom: core::marker::PhantomData<T>,
christine: u32,
}
let opera: Opera<Erik> = Opera {
phantom: core::marker::PhantomData,
christine: 5,
};
CXS::check_codec(&opera, &hex!("05"));
TXS::check_codec(&opera, &hex!("00000005"));
}
#[test]
fn struct_with_tuple_field() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Foo {
x: (u32, u64),
}
let val = Foo { x: (42, 1000) };
let expected = &hex!("2a7fe803");
CXS::check_codec(&val, expected);
let expected = &hex!("0000002a00000000000003e8");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_with_mixed_fields_and_tuple() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Bar {
id: u32,
coords: (i32, i32),
active: bool,
}
let val = Bar {
id: 100,
coords: (-10, 20),
active: true,
};
let expected = &hex!("3f64351401");
CXS::check_codec(&val, expected);
let expected = &hex!("00000064fffffff60000001400000001");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_with_nested_tuple() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Nested {
data: (u32, (i32, bool)),
}
let val = Nested {
data: (5, (-3, false)),
};
let expected = &hex!("053c00");
CXS::check_codec(&val, expected);
let expected = &hex!("00000005fffffffd00000000");
TXS::check_codec(&val, expected);
}
#[test]
fn struct_with_different_tuple_types() {
#[derive(Debug, PartialEq, Eq, WriteXDR, ReadXDR)]
struct Multi {
pair1: (u32, u32),
pair2: (i64, bool),
}
let val = Multi {
pair1: (0xAABBCCDD, 0x11223344),
pair2: (9223372036854775807, true), };
let expected = &hex!("bfddccbbaabf44332211ffffffffffffffff7f01");
CXS::check_codec(&val, expected);
let expected = &hex!("aabbccdd112233447fffffffffffffff00000001");
TXS::check_codec(&val, expected);
}