serializer/machine/
api.rs1use rkyv::Serialize as RkyvSerialize;
16use rkyv::util::AlignedVec;
17
18#[inline(always)]
22pub fn serialize<T>(value: &T) -> Result<AlignedVec, rkyv::rancor::Error>
23where
24 T: for<'a> RkyvSerialize<
25 rkyv::rancor::Strategy<
26 rkyv::ser::Serializer<
27 AlignedVec,
28 rkyv::ser::allocator::ArenaHandle<'a>,
29 rkyv::ser::sharing::Share,
30 >,
31 rkyv::rancor::Error,
32 >,
33 >,
34{
35 rkyv::to_bytes(value)
36}
37
38#[inline(always)]
42pub fn serialize_batch<T>(items: &[T]) -> Result<Vec<AlignedVec>, rkyv::rancor::Error>
43where
44 T: for<'a> RkyvSerialize<
45 rkyv::rancor::Strategy<
46 rkyv::ser::Serializer<
47 AlignedVec,
48 rkyv::ser::allocator::ArenaHandle<'a>,
49 rkyv::ser::sharing::Share,
50 >,
51 rkyv::rancor::Error,
52 >,
53 >,
54{
55 items.iter().map(rkyv::to_bytes).collect()
56}
57
58#[inline(always)]
67#[allow(unsafe_code)]
68pub unsafe fn deserialize<T>(bytes: &[u8]) -> &T::Archived
69where
70 T: rkyv::Archive,
71{
72 unsafe { rkyv::access_unchecked::<T::Archived>(bytes) }
74}
75
76#[inline(always)]
85#[allow(unsafe_code)]
86pub unsafe fn deserialize_batch<T>(batches: &[impl AsRef<[u8]>]) -> Vec<&T::Archived>
87where
88 T: rkyv::Archive,
89{
90 batches
91 .iter()
92 .map(|bytes| unsafe { rkyv::access_unchecked::<T::Archived>(bytes.as_ref()) })
94 .collect()
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use rkyv::{Archive, Deserialize, Serialize as RkyvSerialize};
101
102 #[derive(Archive, RkyvSerialize, Deserialize, Debug, PartialEq)]
103 #[rkyv(compare(PartialEq), derive(Debug))]
104 struct TestPerson {
105 id: u64,
106 age: u32,
107 }
108
109 #[test]
110 #[allow(unsafe_code)]
111 fn test_serialize_single() {
112 let person = TestPerson { id: 1, age: 25 };
113 let bytes = serialize(&person).unwrap();
114 assert!(!bytes.is_empty());
115
116 let archived = unsafe { deserialize::<TestPerson>(&bytes) };
117 assert_eq!(archived.id, 1);
118 assert_eq!(archived.age, 25);
119 }
120
121 #[test]
122 #[allow(unsafe_code)]
123 fn test_serialize_batch() {
124 let items = vec![
125 TestPerson { id: 1, age: 25 },
126 TestPerson { id: 2, age: 30 },
127 TestPerson { id: 3, age: 35 },
128 ];
129
130 let batches = serialize_batch(&items).unwrap();
131 assert_eq!(batches.len(), 3);
132
133 let deserialized = unsafe { deserialize_batch::<TestPerson>(&batches) };
134
135 for (i, archived) in deserialized.iter().enumerate() {
136 assert_eq!(archived.id, items[i].id);
137 assert_eq!(archived.age, items[i].age);
138 }
139 }
140
141 #[test]
142 fn test_batch_vs_individual() {
143 let items: Vec<TestPerson> = (0..1000)
144 .map(|i| TestPerson {
145 id: i,
146 age: (25 + (i % 40)) as u32,
147 })
148 .collect();
149
150 let batch_results = serialize_batch(&items).unwrap();
152 assert_eq!(batch_results.len(), 1000);
153
154 let mut individual_results = Vec::new();
156 for item in &items {
157 individual_results.push(serialize(item).unwrap());
158 }
159 assert_eq!(individual_results.len(), 1000);
160
161 for i in 0..1000 {
163 assert_eq!(batch_results[i].as_ref(), individual_results[i].as_ref());
164 }
165 }
166}