intuicio_framework_serde/
lib.rs1use intuicio_data::type_hash::TypeHash;
2use serde::{Serialize, de::DeserializeOwned};
3use std::{collections::HashMap, error::Error};
4
5pub use serde_intermediate::{
6 Intermediate, Object,
7 de::intermediate::DeserializeMode,
8 error::{Error as IntermediateError, Result as IntermediateResult},
9 from_intermediate, from_intermediate_as, from_object, from_str, from_str_as, to_intermediate,
10 to_object, to_string, to_string_compact, to_string_pretty,
11};
12
13struct Serializer {
14 #[allow(clippy::type_complexity)]
15 serialize_from: Box<dyn Fn(*const u8) -> Result<Intermediate, Box<dyn Error>> + Send + Sync>,
16 #[allow(clippy::type_complexity)]
17 deserialize_to: Box<dyn Fn(*mut u8, &Intermediate) -> Result<(), Box<dyn Error>> + Send + Sync>,
18}
19
20#[derive(Default)]
21pub struct SerializationRegistry {
22 mapping: HashMap<TypeHash, Serializer>,
23}
24
25impl SerializationRegistry {
26 pub fn with_basic_types(mut self) -> Self {
27 self.register::<()>(
28 |_| Ok(Intermediate::Unit),
29 |_, value| {
30 if matches!(value, Intermediate::Unit) {
31 Ok(())
32 } else {
33 Err("Expected unit value".into())
34 }
35 },
36 );
37 self.register::<bool>(
38 |data| Ok((*data).into()),
39 |data, value| {
40 if let Intermediate::Bool(value) = value {
41 *data = *value;
42 Ok(())
43 } else {
44 Err("Expected bool value".into())
45 }
46 },
47 );
48 self.register::<i8>(
49 |data| Ok((*data).into()),
50 |data, value| {
51 if let Intermediate::I8(value) = value {
52 *data = *value;
53 Ok(())
54 } else {
55 Err("Expected i8 value".into())
56 }
57 },
58 );
59 self.register::<i16>(
60 |data| Ok((*data).into()),
61 |data, value| match value {
62 Intermediate::I8(value) => {
63 *data = *value as _;
64 Ok(())
65 }
66 Intermediate::I16(value) => {
67 *data = *value;
68 Ok(())
69 }
70 _ => Err("Expected i16 value".into()),
71 },
72 );
73 self.register::<i32>(
74 |data| Ok((*data).into()),
75 |data, value| match value {
76 Intermediate::I8(value) => {
77 *data = *value as _;
78 Ok(())
79 }
80 Intermediate::I16(value) => {
81 *data = *value as _;
82 Ok(())
83 }
84 Intermediate::I32(value) => {
85 *data = *value;
86 Ok(())
87 }
88 _ => Err("Expected i32 value".into()),
89 },
90 );
91 self.register::<i64>(
92 |data| Ok((*data).into()),
93 |data, value| match value {
94 Intermediate::I8(value) => {
95 *data = *value as _;
96 Ok(())
97 }
98 Intermediate::I16(value) => {
99 *data = *value as _;
100 Ok(())
101 }
102 Intermediate::I32(value) => {
103 *data = *value as _;
104 Ok(())
105 }
106 Intermediate::I64(value) => {
107 *data = *value;
108 Ok(())
109 }
110 _ => Err("Expected i64 value".into()),
111 },
112 );
113 self.register::<i128>(
114 |data| Ok((*data).into()),
115 |data, value| match value {
116 Intermediate::I8(value) => {
117 *data = *value as _;
118 Ok(())
119 }
120 Intermediate::I16(value) => {
121 *data = *value as _;
122 Ok(())
123 }
124 Intermediate::I32(value) => {
125 *data = *value as _;
126 Ok(())
127 }
128 Intermediate::I64(value) => {
129 *data = *value as _;
130 Ok(())
131 }
132 Intermediate::I128(value) => {
133 *data = *value;
134 Ok(())
135 }
136 _ => Err("Expected i128 value".into()),
137 },
138 );
139 self.register::<isize>(
140 |data| Ok((*data).into()),
141 |data, value| match value {
142 Intermediate::I8(value) => {
143 *data = *value as _;
144 Ok(())
145 }
146 Intermediate::I16(value) => {
147 *data = *value as _;
148 Ok(())
149 }
150 Intermediate::I32(value) => {
151 *data = *value as _;
152 Ok(())
153 }
154 Intermediate::I64(value) => {
155 *data = *value as _;
156 Ok(())
157 }
158 _ => Err("Expected isize value".into()),
159 },
160 );
161 self.register::<u8>(
162 |data| Ok((*data).into()),
163 |data, value| {
164 if let Intermediate::U8(value) = value {
165 *data = *value;
166 Ok(())
167 } else {
168 Err("Expected u8 value".into())
169 }
170 },
171 );
172 self.register::<u16>(
173 |data| Ok((*data).into()),
174 |data, value| match value {
175 Intermediate::U8(value) => {
176 *data = *value as _;
177 Ok(())
178 }
179 Intermediate::U16(value) => {
180 *data = *value;
181 Ok(())
182 }
183 _ => Err("Expected u16 value".into()),
184 },
185 );
186 self.register::<u32>(
187 |data| Ok((*data).into()),
188 |data, value| match value {
189 Intermediate::U8(value) => {
190 *data = *value as _;
191 Ok(())
192 }
193 Intermediate::U16(value) => {
194 *data = *value as _;
195 Ok(())
196 }
197 Intermediate::U32(value) => {
198 *data = *value;
199 Ok(())
200 }
201 _ => Err("Expected u32 value".into()),
202 },
203 );
204 self.register::<u64>(
205 |data| Ok((*data).into()),
206 |data, value| match value {
207 Intermediate::U8(value) => {
208 *data = *value as _;
209 Ok(())
210 }
211 Intermediate::U16(value) => {
212 *data = *value as _;
213 Ok(())
214 }
215 Intermediate::U32(value) => {
216 *data = *value as _;
217 Ok(())
218 }
219 Intermediate::U64(value) => {
220 *data = *value;
221 Ok(())
222 }
223 _ => Err("Expected u64 value".into()),
224 },
225 );
226 self.register::<u128>(
227 |data| Ok((*data).into()),
228 |data, value| match value {
229 Intermediate::U8(value) => {
230 *data = *value as _;
231 Ok(())
232 }
233 Intermediate::U16(value) => {
234 *data = *value as _;
235 Ok(())
236 }
237 Intermediate::U32(value) => {
238 *data = *value as _;
239 Ok(())
240 }
241 Intermediate::U64(value) => {
242 *data = *value as _;
243 Ok(())
244 }
245 Intermediate::U128(value) => {
246 *data = *value;
247 Ok(())
248 }
249 _ => Err("Expected u128 value".into()),
250 },
251 );
252 self.register::<usize>(
253 |data| Ok((*data).into()),
254 |data, value| match value {
255 Intermediate::U8(value) => {
256 *data = *value as _;
257 Ok(())
258 }
259 Intermediate::U16(value) => {
260 *data = *value as _;
261 Ok(())
262 }
263 Intermediate::U32(value) => {
264 *data = *value as _;
265 Ok(())
266 }
267 Intermediate::U64(value) => {
268 *data = *value as _;
269 Ok(())
270 }
271 _ => Err("Expected usize value".into()),
272 },
273 );
274 self.register::<f32>(
275 |data| Ok((*data).into()),
276 |data, value| match value {
277 Intermediate::I8(value) => {
278 *data = *value as _;
279 Ok(())
280 }
281 Intermediate::I16(value) => {
282 *data = *value as _;
283 Ok(())
284 }
285 Intermediate::I32(value) => {
286 *data = *value as _;
287 Ok(())
288 }
289 Intermediate::U8(value) => {
290 *data = *value as _;
291 Ok(())
292 }
293 Intermediate::U16(value) => {
294 *data = *value as _;
295 Ok(())
296 }
297 Intermediate::U32(value) => {
298 *data = *value as _;
299 Ok(())
300 }
301 Intermediate::F32(value) => {
302 *data = *value;
303 Ok(())
304 }
305 _ => Err("Expected f32 value".into()),
306 },
307 );
308 self.register::<f64>(
309 |data| Ok((*data).into()),
310 |data, value| match value {
311 Intermediate::I8(value) => {
312 *data = *value as _;
313 Ok(())
314 }
315 Intermediate::I16(value) => {
316 *data = *value as _;
317 Ok(())
318 }
319 Intermediate::I32(value) => {
320 *data = *value as _;
321 Ok(())
322 }
323 Intermediate::I64(value) => {
324 *data = *value as _;
325 Ok(())
326 }
327 Intermediate::U8(value) => {
328 *data = *value as _;
329 Ok(())
330 }
331 Intermediate::U16(value) => {
332 *data = *value as _;
333 Ok(())
334 }
335 Intermediate::U32(value) => {
336 *data = *value as _;
337 Ok(())
338 }
339 Intermediate::U64(value) => {
340 *data = *value as _;
341 Ok(())
342 }
343 Intermediate::F32(value) => {
344 *data = *value as _;
345 Ok(())
346 }
347 Intermediate::F64(value) => {
348 *data = *value;
349 Ok(())
350 }
351 _ => Err("Expected f64 value".into()),
352 },
353 );
354 self.register::<char>(
355 |data| Ok((*data).into()),
356 |data, value| match value {
357 Intermediate::Char(value) => {
358 *data = *value;
359 Ok(())
360 }
361 Intermediate::String(value) => {
362 if let Some(value) = value.chars().next() {
363 *data = value;
364 Ok(())
365 } else {
366 Err("Expected char value (intermediate string is empty)".into())
367 }
368 }
369 _ => Err("Expected char value".into()),
370 },
371 );
372 self.register::<String>(
373 |data| Ok(data.as_str().into()),
374 |data, value| {
375 if let Intermediate::String(value) = value {
376 *data = value.to_owned();
377 Ok(())
378 } else {
379 Err("Expected string value".into())
380 }
381 },
382 );
383 self
384 }
385
386 pub fn with_serde<T: Serialize + DeserializeOwned>(mut self) -> Self {
387 self.register_serde::<T>();
388 self
389 }
390
391 pub fn register_serde<T: Serialize + DeserializeOwned>(&mut self) {
392 self.register::<T>(
393 |data| Ok(serde_intermediate::to_intermediate(data)?),
394 |data, value| {
395 *data = serde_intermediate::from_intermediate(value)?;
396 Ok(())
397 },
398 );
399 }
400
401 pub fn register<T>(
402 &mut self,
403 serialize_from: impl Fn(&T) -> Result<Intermediate, Box<dyn Error>> + Send + Sync + 'static,
404 deserialize_to: impl Fn(&mut T, &Intermediate) -> Result<(), Box<dyn Error>>
405 + Send
406 + Sync
407 + 'static,
408 ) {
409 unsafe {
410 self.register_raw(
411 TypeHash::of::<T>(),
412 move |data| serialize_from(data.cast::<T>().as_ref().unwrap()),
413 move |data, value| deserialize_to(data.cast::<T>().as_mut().unwrap(), value),
414 );
415 }
416 }
417
418 pub unsafe fn register_raw(
420 &mut self,
421 type_hash: TypeHash,
422 serialize_from: impl Fn(*const u8) -> Result<Intermediate, Box<dyn Error>>
423 + Send
424 + Sync
425 + 'static,
426 deserialize_to: impl Fn(*mut u8, &Intermediate) -> Result<(), Box<dyn Error>>
427 + Send
428 + Sync
429 + 'static,
430 ) {
431 self.mapping.insert(
432 type_hash,
433 Serializer {
434 serialize_from: Box::new(serialize_from),
435 deserialize_to: Box::new(deserialize_to),
436 },
437 );
438 }
439
440 pub fn unregister<T>(&mut self) {
441 self.unregister_raw(TypeHash::of::<T>());
442 }
443
444 pub fn unregister_raw(&mut self, type_hash: TypeHash) {
445 self.mapping.remove(&type_hash);
446 }
447
448 pub fn serialize_from<T>(&self, data: &T) -> Result<Intermediate, Box<dyn Error>> {
449 unsafe { self.dynamic_serialize_from(TypeHash::of::<T>(), data as *const T as *const u8) }
450 }
451
452 pub unsafe fn dynamic_serialize_from(
454 &self,
455 type_hash: TypeHash,
456 data: *const u8,
457 ) -> Result<Intermediate, Box<dyn Error>> {
458 if let Some(serializer) = self.mapping.get(&type_hash) {
459 return (serializer.serialize_from)(data);
460 }
461 Err("Type not existent in serialization registry".into())
462 }
463
464 pub fn deserialize_to<T: Default>(&self, value: &Intermediate) -> Result<T, Box<dyn Error>> {
465 let mut result = T::default();
466 unsafe {
467 self.dynamic_deserialize_to(
468 TypeHash::of::<T>(),
469 &mut result as *mut T as *mut u8,
470 value,
471 )?;
472 }
473 Ok(result)
474 }
475
476 pub unsafe fn dynamic_deserialize_to(
478 &self,
479 type_hash: TypeHash,
480 data: *mut u8,
481 value: &Intermediate,
482 ) -> Result<(), Box<dyn Error>> {
483 if let Some(serializer) = self.mapping.get(&type_hash) {
484 (serializer.deserialize_to)(data, value)?;
485 return Ok(());
486 }
487 Err("Type not existent in serialization registry".into())
488 }
489}
490
491#[cfg(test)]
492mod tests {
493 use super::*;
494 use intuicio_derive::{IntuicioEnum, IntuicioStruct};
495 use serde::Deserialize;
496
497 #[derive(IntuicioEnum, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
498 #[repr(u8)]
499 enum Skill {
500 #[default]
501 Brain,
502 Muscles(bool),
503 Magic {
504 power: i32,
505 },
506 }
507
508 #[derive(IntuicioStruct, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
509 struct Person {
510 name: String,
511 age: usize,
512 skill: Skill,
513 }
514
515 #[test]
516 fn test_serialization() {
517 let serialization = SerializationRegistry::default()
518 .with_basic_types()
519 .with_serde::<Skill>()
520 .with_serde::<Person>();
521
522 let person = Person {
523 name: "Grumpy".to_owned(),
524 age: 24,
525 skill: Skill::Magic { power: 42 },
526 };
527 let serialized = serialization.serialize_from(&person).unwrap();
528 let person2 = serialization.deserialize_to::<Person>(&serialized).unwrap();
529 assert_eq!(person, person2);
530 }
531}