#![allow(deprecated)]
use core::marker::PhantomData;
use epserde::PhantomDeserData;
use epserde::TypeInfo;
use epserde::prelude::*;
#[test]
fn test_phantom() -> anyhow::Result<()> {
let obj = PhantomData::<usize>;
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <PhantomData<usize>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
println!();
let eps = unsafe { <PhantomData<usize>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps, obj);
Ok(())
}
#[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
#[epserde(deep_copy)]
struct DataFull<D> {
a: usize,
b: PhantomData<D>,
}
#[derive(Debug, PartialEq, Eq, Clone, Default, TypeInfo)]
struct NotSerializableType;
#[test]
fn test_not_serializable_in_phantom() -> anyhow::Result<()> {
let obj = <DataFull<NotSerializableType>>::default();
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <DataFull<NotSerializableType>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
println!();
cursor.set_position(0);
let eps = unsafe { <DataFull<NotSerializableType>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.a, obj.a);
Ok(())
}
#[derive(Epserde, Copy, Debug, PartialEq, Eq, Clone, Default)]
#[repr(C)]
#[epserde(zero_copy)]
struct DataZero<A: Default + ZeroCopy> {
a: usize,
b: PhantomData<A>,
}
#[derive(Epserde, Debug, Copy, PartialEq, Eq, Clone, Default)]
#[repr(C)]
#[epserde(zero_copy)]
struct ZeroCopyType;
#[test]
fn test_phantom_zero_copy() -> anyhow::Result<()> {
let obj = <DataZero<ZeroCopyType>>::default();
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let zero = unsafe { <DataZero<ZeroCopyType>>::deserialize_full(&mut cursor)? };
assert_eq!(zero, obj);
println!();
cursor.set_position(0);
let eps = unsafe { <DataZero<ZeroCopyType>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.a, obj.a);
Ok(())
}
#[derive(Epserde, Copy, Debug, PartialEq, Eq, Clone, Default)]
#[repr(C)]
#[epserde(zero_copy)]
struct OnlyPhantom<A: Default + ZeroCopy> {
a: PhantomData<A>,
b: PhantomData<(A, A)>,
}
#[test]
fn test_only_phantom() -> anyhow::Result<()> {
let obj = <OnlyPhantom<ZeroCopyType>>::default();
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let zero = unsafe { <OnlyPhantom<ZeroCopyType>>::deserialize_full(&mut cursor)? };
assert_eq!(zero, obj);
println!();
cursor.set_position(0);
let eps = unsafe { <OnlyPhantom<ZeroCopyType>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.a, obj.a);
let vec = vec![<OnlyPhantom<ZeroCopyType>>::default(); 10];
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { vec.serialize(&mut cursor)? };
cursor.set_position(0);
let zero = unsafe { <Vec<OnlyPhantom<ZeroCopyType>>>::deserialize_full(&mut cursor)? };
assert_eq!(zero, vec);
println!();
cursor.set_position(0);
let eps = unsafe { <Vec<OnlyPhantom<ZeroCopyType>>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps, vec);
Ok(())
}
#[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
struct DataWithPhantomDeserData<T> {
data: T,
phantom: PhantomDeserData<T>,
}
#[test]
fn test_deser_phantom_deep_copy() -> anyhow::Result<()> {
let obj = DataWithPhantomDeserData {
data: vec![1, 2, 3, 4],
phantom: PhantomDeserData(PhantomData),
};
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <DataWithPhantomDeserData<Vec<i32>>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
cursor.set_position(0);
let eps = unsafe { <DataWithPhantomDeserData<Vec<i32>>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.data, obj.data.as_slice());
let _phantom_check: PhantomDeserData<&[i32]> = eps.phantom;
Ok(())
}
#[derive(Epserde, Copy, Debug, PartialEq, Eq, Clone, Default)]
#[repr(C)]
#[epserde(zero_copy)]
struct DataZeroWithPhantomDeserData<T: ZeroCopy> {
data: T,
phantom: PhantomDeserData<T>,
}
#[test]
fn test_deser_phantom_zero_copy() -> anyhow::Result<()> {
let obj = DataZeroWithPhantomDeserData {
data: [1, 2, 3, 4],
phantom: PhantomDeserData(PhantomData),
};
let mut cursor = <AlignedCursor<Aligned16>>::new();
let _bytes_written = unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <DataZeroWithPhantomDeserData<[i32; 4]>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
cursor.set_position(0);
let eps =
unsafe { <DataZeroWithPhantomDeserData<[i32; 4]>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.data, obj.data.as_slice());
let _phantom_check: PhantomDeserData<[i32; 4]> = eps.phantom;
Ok(())
}
#[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
struct DataWithPhantomData<T> {
data: T,
phantom: PhantomData<T>,
}
#[test]
fn test_phantom_data_substitution() -> anyhow::Result<()> {
let obj: DataWithPhantomData<Vec<i32>> = DataWithPhantomData {
data: vec![1, 2, 3, 4],
phantom: PhantomData,
};
let mut cursor = <AlignedCursor<Aligned16>>::new();
unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <DataWithPhantomData<Vec<i32>>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
let eps = unsafe { <DataWithPhantomData<Vec<i32>>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.data, obj.data.as_slice());
let _phantom_check: PhantomData<&[i32]> = eps.phantom;
Ok(())
}
#[derive(Epserde, Debug, PartialEq, Eq, Clone, Default)]
#[epserde(deep_copy)]
struct OnlyPhantomDeserData<T> {
other: u32,
phantom: PhantomDeserData<T>,
}
#[test]
fn test_only_phantom_deser_data() -> anyhow::Result<()> {
let obj: OnlyPhantomDeserData<Vec<i32>> = OnlyPhantomDeserData {
other: 42,
phantom: PhantomDeserData(PhantomData),
};
let mut cursor = <AlignedCursor<Aligned16>>::new();
unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <OnlyPhantomDeserData<Vec<i32>>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
let eps = unsafe { <OnlyPhantomDeserData<Vec<i32>>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.other, obj.other);
let _phantom_check: PhantomDeserData<&[i32]> = eps.phantom;
Ok(())
}
#[test]
fn test_leading_separator_phantom_data() -> anyhow::Result<()> {
#[derive(Epserde, Debug, PartialEq, Eq, Clone)]
struct Data<T: DeepCopy> {
data: Vec<T>,
marker: ::core::marker::PhantomData<T>,
}
let obj = Data::<Vec<i32>> {
data: vec![vec![1], vec![2, 3]],
marker: PhantomData,
};
let mut cursor = <AlignedCursor<Aligned16>>::new();
unsafe { obj.serialize(&mut cursor)? };
cursor.set_position(0);
let full = unsafe { <Data<Vec<i32>>>::deserialize_full(&mut cursor)? };
assert_eq!(full, obj);
let eps = unsafe { <Data<Vec<i32>>>::deserialize_eps(cursor.as_bytes())? };
assert_eq!(eps.data, vec![&[1_i32][..], &[2, 3][..]]);
Ok(())
}
#[test]
fn test_type_info_generic_zero_copy() {
use epserde::traits::{AlignHash, PadTo};
#[allow(dead_code)]
#[derive(TypeInfo, Copy, Clone)]
#[repr(C)]
#[epserde(zero_copy)]
struct GenericZero<T: TypeHash + AlignHash + PadTo + Copy + 'static> {
x: T,
}
let mut hasher = CryptoHasher::new();
<GenericZero<u32>>::type_hash(&mut hasher);
assert_ne!(hasher.finalize(), [0u8; 32]);
}