1use intuicio_core::{
2 object::Object as CoreObject,
3 registry::Registry,
4 types::{
5 EnumVariantQuery, Type, TypeHandle, TypeQuery, enum_type::Enum, struct_type::StructField,
6 },
7};
8use intuicio_data::{
9 Finalize, managed::DynamicManaged, managed_box::DynamicManagedBox, type_hash::TypeHash,
10};
11use serde::{Serialize, de::DeserializeOwned};
12use std::{collections::HashMap, error::Error};
13
14pub use serde_intermediate::{
15 Intermediate, Object,
16 de::intermediate::DeserializeMode,
17 error::{Error as IntermediateError, Result as IntermediateResult},
18 from_intermediate, from_intermediate_as, from_object, from_str, from_str_as, to_intermediate,
19 to_object, to_string, to_string_compact, to_string_pretty,
20};
21
22struct Serializer {
23 #[allow(clippy::type_complexity)]
24 serialize_from: Box<
25 dyn Fn(*const u8, &SerializationRegistry, &Registry) -> Result<Intermediate, Box<dyn Error>>
26 + Send
27 + Sync,
28 >,
29 #[allow(clippy::type_complexity)]
30 deserialize_to: Box<
31 dyn Fn(
32 *mut u8,
33 &Intermediate,
34 &SerializationRegistry,
35 bool,
36 &Registry,
37 ) -> Result<(), Box<dyn Error>>
38 + Send
39 + Sync,
40 >,
41}
42
43#[derive(Default)]
44pub struct SerializationRegistry {
45 mapping: HashMap<TypeHash, Serializer>,
46}
47
48impl SerializationRegistry {
49 pub fn with_basic_types(mut self) -> Self {
50 self.register::<()>(
51 |_, _, _| Ok(Intermediate::Unit),
52 |_, value, _, _, _| {
53 if matches!(value, Intermediate::Unit) {
54 Ok(())
55 } else {
56 Err("Expected unit value".into())
57 }
58 },
59 );
60 self.register::<bool>(
61 |data, _, _| Ok((*data).into()),
62 |data, value, _, _, _| {
63 if let Intermediate::Bool(value) = value {
64 *data = *value;
65 Ok(())
66 } else {
67 Err("Expected bool value".into())
68 }
69 },
70 );
71 self.register::<i8>(
72 |data, _, _| Ok((*data).into()),
73 |data, value, _, _, _| {
74 if let Intermediate::I8(value) = value {
75 *data = *value;
76 Ok(())
77 } else {
78 Err("Expected i8 value".into())
79 }
80 },
81 );
82 self.register::<i16>(
83 |data, _, _| Ok((*data).into()),
84 |data, value, _, _, _| match value {
85 Intermediate::I8(value) => {
86 *data = *value as _;
87 Ok(())
88 }
89 Intermediate::I16(value) => {
90 *data = *value;
91 Ok(())
92 }
93 _ => Err("Expected i16 value".into()),
94 },
95 );
96 self.register::<i32>(
97 |data, _, _| Ok((*data).into()),
98 |data, value, _, _, _| match value {
99 Intermediate::I8(value) => {
100 *data = *value as _;
101 Ok(())
102 }
103 Intermediate::I16(value) => {
104 *data = *value as _;
105 Ok(())
106 }
107 Intermediate::I32(value) => {
108 *data = *value;
109 Ok(())
110 }
111 _ => Err("Expected i32 value".into()),
112 },
113 );
114 self.register::<i64>(
115 |data, _, _| Ok((*data).into()),
116 |data, value, _, _, _| match value {
117 Intermediate::I8(value) => {
118 *data = *value as _;
119 Ok(())
120 }
121 Intermediate::I16(value) => {
122 *data = *value as _;
123 Ok(())
124 }
125 Intermediate::I32(value) => {
126 *data = *value as _;
127 Ok(())
128 }
129 Intermediate::I64(value) => {
130 *data = *value;
131 Ok(())
132 }
133 _ => Err("Expected i64 value".into()),
134 },
135 );
136 self.register::<i128>(
137 |data, _, _| Ok((*data).into()),
138 |data, value, _, _, _| match value {
139 Intermediate::I8(value) => {
140 *data = *value as _;
141 Ok(())
142 }
143 Intermediate::I16(value) => {
144 *data = *value as _;
145 Ok(())
146 }
147 Intermediate::I32(value) => {
148 *data = *value as _;
149 Ok(())
150 }
151 Intermediate::I64(value) => {
152 *data = *value as _;
153 Ok(())
154 }
155 Intermediate::I128(value) => {
156 *data = *value;
157 Ok(())
158 }
159 _ => Err("Expected i128 value".into()),
160 },
161 );
162 self.register::<isize>(
163 |data, _, _| Ok((*data).into()),
164 |data, value, _, _, _| match value {
165 Intermediate::I8(value) => {
166 *data = *value as _;
167 Ok(())
168 }
169 Intermediate::I16(value) => {
170 *data = *value as _;
171 Ok(())
172 }
173 Intermediate::I32(value) => {
174 *data = *value as _;
175 Ok(())
176 }
177 Intermediate::I64(value) => {
178 *data = *value as _;
179 Ok(())
180 }
181 _ => Err("Expected isize value".into()),
182 },
183 );
184 self.register::<u8>(
185 |data, _, _| Ok((*data).into()),
186 |data, value, _, _, _| {
187 if let Intermediate::U8(value) = value {
188 *data = *value;
189 Ok(())
190 } else {
191 Err("Expected u8 value".into())
192 }
193 },
194 );
195 self.register::<u16>(
196 |data, _, _| Ok((*data).into()),
197 |data, value, _, _, _| match value {
198 Intermediate::U8(value) => {
199 *data = *value as _;
200 Ok(())
201 }
202 Intermediate::U16(value) => {
203 *data = *value;
204 Ok(())
205 }
206 _ => Err("Expected u16 value".into()),
207 },
208 );
209 self.register::<u32>(
210 |data, _, _| Ok((*data).into()),
211 |data, value, _, _, _| match value {
212 Intermediate::U8(value) => {
213 *data = *value as _;
214 Ok(())
215 }
216 Intermediate::U16(value) => {
217 *data = *value as _;
218 Ok(())
219 }
220 Intermediate::U32(value) => {
221 *data = *value;
222 Ok(())
223 }
224 _ => Err("Expected u32 value".into()),
225 },
226 );
227 self.register::<u64>(
228 |data, _, _| Ok((*data).into()),
229 |data, value, _, _, _| match value {
230 Intermediate::U8(value) => {
231 *data = *value as _;
232 Ok(())
233 }
234 Intermediate::U16(value) => {
235 *data = *value as _;
236 Ok(())
237 }
238 Intermediate::U32(value) => {
239 *data = *value as _;
240 Ok(())
241 }
242 Intermediate::U64(value) => {
243 *data = *value;
244 Ok(())
245 }
246 _ => Err("Expected u64 value".into()),
247 },
248 );
249 self.register::<u128>(
250 |data, _, _| Ok((*data).into()),
251 |data, value, _, _, _| match value {
252 Intermediate::U8(value) => {
253 *data = *value as _;
254 Ok(())
255 }
256 Intermediate::U16(value) => {
257 *data = *value as _;
258 Ok(())
259 }
260 Intermediate::U32(value) => {
261 *data = *value as _;
262 Ok(())
263 }
264 Intermediate::U64(value) => {
265 *data = *value as _;
266 Ok(())
267 }
268 Intermediate::U128(value) => {
269 *data = *value;
270 Ok(())
271 }
272 _ => Err("Expected u128 value".into()),
273 },
274 );
275 self.register::<usize>(
276 |data, _, _| Ok((*data).into()),
277 |data, value, _, _, _| match value {
278 Intermediate::U8(value) => {
279 *data = *value as _;
280 Ok(())
281 }
282 Intermediate::U16(value) => {
283 *data = *value as _;
284 Ok(())
285 }
286 Intermediate::U32(value) => {
287 *data = *value as _;
288 Ok(())
289 }
290 Intermediate::U64(value) => {
291 *data = *value as _;
292 Ok(())
293 }
294 _ => Err("Expected usize value".into()),
295 },
296 );
297 self.register::<f32>(
298 |data, _, _| Ok((*data).into()),
299 |data, value, _, _, _| match value {
300 Intermediate::I8(value) => {
301 *data = *value as _;
302 Ok(())
303 }
304 Intermediate::I16(value) => {
305 *data = *value as _;
306 Ok(())
307 }
308 Intermediate::I32(value) => {
309 *data = *value as _;
310 Ok(())
311 }
312 Intermediate::U8(value) => {
313 *data = *value as _;
314 Ok(())
315 }
316 Intermediate::U16(value) => {
317 *data = *value as _;
318 Ok(())
319 }
320 Intermediate::U32(value) => {
321 *data = *value as _;
322 Ok(())
323 }
324 Intermediate::F32(value) => {
325 *data = *value;
326 Ok(())
327 }
328 _ => Err("Expected f32 value".into()),
329 },
330 );
331 self.register::<f64>(
332 |data, _, _| Ok((*data).into()),
333 |data, value, _, _, _| match value {
334 Intermediate::I8(value) => {
335 *data = *value as _;
336 Ok(())
337 }
338 Intermediate::I16(value) => {
339 *data = *value as _;
340 Ok(())
341 }
342 Intermediate::I32(value) => {
343 *data = *value as _;
344 Ok(())
345 }
346 Intermediate::I64(value) => {
347 *data = *value as _;
348 Ok(())
349 }
350 Intermediate::U8(value) => {
351 *data = *value as _;
352 Ok(())
353 }
354 Intermediate::U16(value) => {
355 *data = *value as _;
356 Ok(())
357 }
358 Intermediate::U32(value) => {
359 *data = *value as _;
360 Ok(())
361 }
362 Intermediate::U64(value) => {
363 *data = *value as _;
364 Ok(())
365 }
366 Intermediate::F32(value) => {
367 *data = *value as _;
368 Ok(())
369 }
370 Intermediate::F64(value) => {
371 *data = *value;
372 Ok(())
373 }
374 _ => Err("Expected f64 value".into()),
375 },
376 );
377 self.register::<char>(
378 |data, _, _| Ok((*data).into()),
379 |data, value, _, _, _| match value {
380 Intermediate::Char(value) => {
381 *data = *value;
382 Ok(())
383 }
384 Intermediate::String(value) => {
385 if let Some(value) = value.chars().next() {
386 *data = value;
387 Ok(())
388 } else {
389 Err("Expected char value (intermediate string is empty)".into())
390 }
391 }
392 _ => Err("Expected char value".into()),
393 },
394 );
395 self.register::<String>(
396 |data, _, _| Ok(data.as_str().into()),
397 |data, value, _, initialized, _| {
398 if let Intermediate::String(value) = value {
399 if initialized {
400 *data = value.to_owned();
401 } else {
402 unsafe { (data as *mut String).write_unaligned(value.to_owned()) };
403 }
404 Ok(())
405 } else {
406 Err("Expected string value".into())
407 }
408 },
409 );
410 self
411 }
412
413 pub fn with_erased_types(mut self) -> Self {
414 self.register::<DynamicManaged>(
415 |data, serializer, registry| unsafe {
416 let Some(type_handle) = registry.find_type(TypeQuery {
417 type_hash: Some(*data.type_hash()),
418 ..Default::default()
419 }) else {
420 return Err(format!(
421 "Type of DynamicManaged object not found. Hash: {}",
422 data.type_hash()
423 )
424 .into());
425 };
426 let value = serializer
427 .dynamic_serialize_from(*data.type_hash(), data.as_ptr_raw(), registry)
428 .map_err(|error| {
429 format!(
430 "{}. Type: {}::{}",
431 error,
432 type_handle.module_name().unwrap_or(""),
433 type_handle.name()
434 )
435 })?;
436 Ok(Intermediate::struct_type()
437 .field("type", type_handle.name())
438 .field(
439 "module",
440 Intermediate::Option(
441 type_handle
442 .module_name()
443 .map(|name| Box::new(Intermediate::String(name.to_owned()))),
444 ),
445 )
446 .field("value", value))
447 },
448 |data, value, serializer, initialized, registry| unsafe {
449 let Intermediate::Struct(fields) = value else {
450 return Err("Expected struct value".into());
451 };
452 let Some(type_name) = fields
453 .iter()
454 .find(|(name, _)| name == "type")
455 .and_then(|(_, value)| value.as_str())
456 else {
457 return Err("Type field not found".into());
458 };
459 let Some(module_name) = fields
460 .iter()
461 .find(|(name, _)| name == "module")
462 .map(|(_, value)| value.as_option().and_then(|value| value.as_str()))
463 else {
464 return Err("Module field not found".into());
465 };
466 let Some(value) = fields
467 .iter()
468 .find(|(name, _)| name == "value")
469 .map(|(_, value)| value)
470 else {
471 return Err("Value field not found".into());
472 };
473 let Some(type_handle) = registry.find_type(TypeQuery {
474 name: Some(type_name.into()),
475 module_name: module_name.map(|name| name.into()),
476 ..Default::default()
477 }) else {
478 return Err(format!(
479 "Type not found: {}::{}",
480 module_name.unwrap_or(""),
481 type_name
482 )
483 .into());
484 };
485 if initialized {
486 DynamicManaged::finalize_raw(data as *mut DynamicManaged as *mut ());
487 }
488 (data as *mut DynamicManaged).write_unaligned(DynamicManaged::new_uninitialized(
489 type_handle.type_hash(),
490 *type_handle.layout(),
491 type_handle.finalizer(),
492 ));
493 serializer.dynamic_deserialize_to(
494 type_handle.type_hash(),
495 data.as_mut_ptr_raw(),
496 value,
497 false,
498 registry,
499 )
500 },
501 );
502 self.register::<DynamicManagedBox>(
503 |data, serializer, registry| unsafe {
504 let Some(type_hash) = data.type_hash() else {
505 return Err("DynamicManagedBox type hash not found".into());
506 };
507 let Some(ptr) = data.as_ptr_raw() else {
508 return Err("DynamicManagedBox pointer not found".into());
509 };
510 let Some(type_handle) = registry.find_type(TypeQuery {
511 type_hash: Some(type_hash),
512 ..Default::default()
513 }) else {
514 return Err(format!(
515 "Type of DynamicManagedBox object not found. Hash: {}",
516 type_hash
517 )
518 .into());
519 };
520 let value = serializer
521 .dynamic_serialize_from(type_hash, ptr, registry)
522 .map_err(|error| {
523 format!(
524 "{}. Type: {}::{}",
525 error,
526 type_handle.module_name().unwrap_or(""),
527 type_handle.name()
528 )
529 })?;
530 Ok(Intermediate::struct_type()
531 .field("type", type_handle.name())
532 .field(
533 "module",
534 Intermediate::Option(
535 type_handle
536 .module_name()
537 .map(|name| Box::new(Intermediate::String(name.to_owned()))),
538 ),
539 )
540 .field("value", value))
541 },
542 |data, value, serializer, initialized, registry| unsafe {
543 let Intermediate::Struct(fields) = value else {
544 return Err("Expected struct value".into());
545 };
546 let Some(type_name) = fields
547 .iter()
548 .find(|(name, _)| name == "type")
549 .and_then(|(_, value)| value.as_str())
550 else {
551 return Err("Type field not found".into());
552 };
553 let Some(module_name) = fields
554 .iter()
555 .find(|(name, _)| name == "module")
556 .map(|(_, value)| value.as_option().and_then(|value| value.as_str()))
557 else {
558 return Err("Module field not found".into());
559 };
560 let Some(value) = fields
561 .iter()
562 .find(|(name, _)| name == "value")
563 .map(|(_, value)| value)
564 else {
565 return Err("Value field not found".into());
566 };
567 let Some(type_handle) = registry.find_type(TypeQuery {
568 name: Some(type_name.into()),
569 module_name: module_name.map(|name| name.into()),
570 ..Default::default()
571 }) else {
572 return Err(format!(
573 "Type not found: {}::{}",
574 module_name.unwrap_or(""),
575 type_name
576 )
577 .into());
578 };
579 if initialized {
580 DynamicManagedBox::finalize_raw(data as *mut DynamicManagedBox as *mut ());
581 }
582 (data as *mut DynamicManagedBox).write_unaligned(
583 DynamicManagedBox::new_uninitialized(
584 type_handle.type_hash(),
585 *type_handle.layout(),
586 type_handle.finalizer(),
587 ),
588 );
589 serializer.dynamic_deserialize_to(
590 type_handle.type_hash(),
591 data.as_mut_ptr_raw().unwrap(),
592 value,
593 false,
594 registry,
595 )
596 },
597 );
598 self.register::<CoreObject>(
599 |data, serializer, registry| unsafe {
600 let Some(type_handle) = registry.find_type(TypeQuery {
601 type_hash: Some(data.type_handle().type_hash()),
602 ..Default::default()
603 }) else {
604 return Err(format!(
605 "Type of Object not found. Hash: {}",
606 data.type_handle().type_hash()
607 )
608 .into());
609 };
610 let value = serializer
611 .dynamic_serialize_from(data.type_handle().type_hash(), data.as_ptr(), registry)
612 .map_err(|error| {
613 format!(
614 "{}. Type: {}::{}",
615 error,
616 type_handle.module_name().unwrap_or(""),
617 type_handle.name()
618 )
619 })?;
620 Ok(Intermediate::struct_type()
621 .field("type", type_handle.name())
622 .field(
623 "module",
624 Intermediate::Option(
625 type_handle
626 .module_name()
627 .map(|name| Box::new(Intermediate::String(name.to_owned()))),
628 ),
629 )
630 .field("value", value))
631 },
632 |data, value, serializer, initialized, registry| unsafe {
633 let Intermediate::Struct(fields) = value else {
634 return Err("Expected struct value".into());
635 };
636 let Some(type_name) = fields
637 .iter()
638 .find(|(name, _)| name == "type")
639 .and_then(|(_, value)| value.as_str())
640 else {
641 return Err("Type field not found".into());
642 };
643 let Some(module_name) = fields
644 .iter()
645 .find(|(name, _)| name == "module")
646 .map(|(_, value)| value.as_option().and_then(|value| value.as_str()))
647 else {
648 return Err("Module field not found".into());
649 };
650 let Some(value) = fields
651 .iter()
652 .find(|(name, _)| name == "value")
653 .map(|(_, value)| value)
654 else {
655 return Err("Value field not found".into());
656 };
657 let Some(type_handle) = registry.find_type(TypeQuery {
658 name: Some(type_name.into()),
659 module_name: module_name.map(|name| name.into()),
660 ..Default::default()
661 }) else {
662 return Err(format!(
663 "Type not found: {}::{}",
664 module_name.unwrap_or(""),
665 type_name
666 )
667 .into());
668 };
669 if initialized {
670 CoreObject::finalize_raw(data as *mut CoreObject as *mut ());
671 }
672 (data as *mut CoreObject)
673 .write_unaligned(CoreObject::new_uninitialized(type_handle.clone()).unwrap());
674 serializer.dynamic_deserialize_to(
675 type_handle.type_hash(),
676 data.as_mut_ptr(),
677 value,
678 false,
679 registry,
680 )
681 },
682 );
683 self
684 }
685
686 pub fn with_serde<T: Serialize + DeserializeOwned>(mut self) -> Self {
687 self.register_serde::<T>();
688 self
689 }
690
691 pub fn with_reflection(mut self, handle: TypeHandle) -> Self {
692 self.register_reflection(handle);
693 self
694 }
695
696 pub fn with<T>(
697 mut self,
698 serialize_from: impl Fn(&T, &Self, &Registry) -> Result<Intermediate, Box<dyn Error>>
699 + Send
700 + Sync
701 + 'static,
702 deserialize_to: impl Fn(
703 &mut T,
704 &Intermediate,
705 &Self,
706 bool,
707 &Registry,
708 ) -> Result<(), Box<dyn Error>>
709 + Send
710 + Sync
711 + 'static,
712 ) -> Self {
713 self.register(serialize_from, deserialize_to);
714 self
715 }
716
717 pub fn with_raw(
718 mut self,
719 type_hash: TypeHash,
720 serialize_from: impl Fn(*const u8, &Self, &Registry) -> Result<Intermediate, Box<dyn Error>>
721 + Send
722 + Sync
723 + 'static,
724 deserialize_to: impl Fn(
725 *mut u8,
726 &Intermediate,
727 &Self,
728 bool,
729 &Registry,
730 ) -> Result<(), Box<dyn Error>>
731 + Send
732 + Sync
733 + 'static,
734 ) -> Self {
735 unsafe { self.register_raw(type_hash, serialize_from, deserialize_to) }
736 self
737 }
738
739 pub fn register_serde<T: Serialize + DeserializeOwned>(&mut self) {
740 self.register::<T>(
741 |data, _, _| Ok(serde_intermediate::to_intermediate(data)?),
742 |data, value, _, initialized, _| {
743 if initialized {
744 *data = serde_intermediate::from_intermediate(value)?;
745 } else {
746 unsafe {
747 (data as *mut T)
748 .write_unaligned(serde_intermediate::from_intermediate(value)?)
749 };
750 }
751 Ok(())
752 },
753 );
754 }
755
756 pub fn register_reflection(&mut self, handle: TypeHandle) {
757 let handle_ser = handle.clone();
758 let handle_de = handle.clone();
759 unsafe {
760 self.register_raw(
761 handle.type_hash(),
762 move |data, serializer, registry| match &*handle_ser {
763 Type::Struct(type_) => {
764 let mut result = Intermediate::struct_type();
765 for field in type_.fields() {
766 let value = serializer.dynamic_serialize_from(
767 field.type_handle().type_hash(),
768 data.add(field.address_offset()),
769 registry,
770 )?;
771 result = result.field(field.name.as_str(), value);
772 }
773 Ok(result)
774 }
775 Type::Enum(type_) => {
776 let discriminant = data.read();
777 if let Some(variant) = type_.find_variant_by_discriminant(discriminant) {
778 let mut result = Intermediate::struct_variant(variant.name.as_str());
779 for field in &variant.fields {
780 let value = serializer.dynamic_serialize_from(
781 field.type_handle().type_hash(),
782 data.add(field.address_offset()),
783 registry,
784 )?;
785 result = result.field(field.name.as_str(), value);
786 }
787 Ok(result)
788 } else {
789 Err(format!(
790 "Enum variant with discriminant: {} not found",
791 discriminant
792 )
793 .into())
794 }
795 }
796 },
797 move |data, value, serializer, initialized, registry| match &*handle_de {
798 Type::Struct(type_) => {
799 fn item<'a>(
800 value: &'a Intermediate,
801 name: &'a str,
802 ) -> Option<&'a Intermediate> {
803 match value {
804 Intermediate::Struct(value) => value
805 .iter()
806 .find_map(|(n, v)| if n == name { Some(v) } else { None }),
807 Intermediate::Map(value) => value.iter().find_map(|(key, v)| {
808 if key.as_str().map(|key| key == name).unwrap_or_default() {
809 Some(v)
810 } else {
811 None
812 }
813 }),
814 _ => None,
815 }
816 }
817 for field in type_.fields() {
818 let data = data.add(field.address_offset());
819 if initialized {
820 field.type_handle().finalize(data.cast());
821 }
822 if let Some(value) = item(value, &field.name) {
823 serializer.dynamic_deserialize_to(
824 field.type_handle().type_hash(),
825 data,
826 value,
827 false,
828 registry,
829 )?;
830 } else if !initialized {
831 field.type_handle().initialize(data.cast());
832 }
833 }
834 Ok(())
835 }
836 Type::Enum(type_) => {
837 fn discriminant_fields<'a>(
838 type_: &'a Enum,
839 name: &'a str,
840 ) -> Option<(u8, &'a [StructField])> {
841 type_
842 .find_variant(EnumVariantQuery {
843 name: Some(name.into()),
844 ..Default::default()
845 })
846 .map(|variant| (variant.discriminant(), variant.fields.as_slice()))
847 }
848 if initialized {
849 type_.finalize(data.cast());
850 }
851 match value {
852 Intermediate::UnitVariant(name) => {
853 if let Some((discriminant, _)) = discriminant_fields(type_, name) {
854 data.write_unaligned(discriminant);
855 } else {
856 return Err(format!("Enum variant: {} not found", name).into());
857 }
858 }
859 Intermediate::NewTypeVariant(name, value) => {
860 if let Some((discriminant, fields)) =
861 discriminant_fields(type_, name)
862 {
863 let field = &fields[0];
864 data.write_unaligned(discriminant);
865 serializer.dynamic_deserialize_to(
866 field.type_handle().type_hash(),
867 data.add(field.address_offset()),
868 value,
869 false,
870 registry,
871 )?;
872 } else {
873 return Err(format!("Enum variant: {} not found", name).into());
874 }
875 }
876 Intermediate::TupleVariant(name, values) => {
877 if let Some((discriminant, fields)) =
878 discriminant_fields(type_, name)
879 {
880 data.write_unaligned(discriminant);
881 for field in fields {
882 let index = field
883 .name
884 .parse::<usize>()
885 .map_err(|_| "Expected tuple field name")?;
886 if let Some(value) = values.get(index) {
887 serializer.dynamic_deserialize_to(
888 field.type_handle().type_hash(),
889 data.add(field.address_offset()),
890 value,
891 false,
892 registry,
893 )?;
894 } else if !initialized {
895 field.type_handle().initialize(
896 data.add(field.address_offset()).cast(),
897 );
898 }
899 }
900 } else {
901 return Err(format!("Enum variant: {} not found", name).into());
902 }
903 }
904 Intermediate::StructVariant(name, values) => {
905 if let Some((discriminant, fields)) =
906 discriminant_fields(type_, name)
907 {
908 data.write_unaligned(discriminant);
909 for field in fields {
910 if let Some((_, value)) = values
911 .iter()
912 .find(|(key, _)| key == field.name.as_str())
913 {
914 serializer.dynamic_deserialize_to(
915 field.type_handle().type_hash(),
916 data.add(field.address_offset()),
917 value,
918 false,
919 registry,
920 )?;
921 } else if !initialized {
922 field.type_handle().initialize(
923 data.add(field.address_offset()).cast(),
924 );
925 }
926 }
927 } else {
928 return Err(format!("Enum variant: {} not found", name).into());
929 }
930 }
931 _ => return Err("Expected enum variant".into()),
932 }
933 Ok(())
934 }
935 },
936 );
937 }
938 }
939
940 pub fn register<T>(
941 &mut self,
942 serialize_from: impl Fn(&T, &Self, &Registry) -> Result<Intermediate, Box<dyn Error>>
943 + Send
944 + Sync
945 + 'static,
946 deserialize_to: impl Fn(
947 &mut T,
948 &Intermediate,
949 &Self,
950 bool,
951 &Registry,
952 ) -> Result<(), Box<dyn Error>>
953 + Send
954 + Sync
955 + 'static,
956 ) {
957 let type_hash = TypeHash::of::<T>();
958 unsafe {
959 self.register_raw(
960 type_hash,
961 move |data, serializer, registry| {
962 serialize_from(data.cast::<T>().as_ref().unwrap(), serializer, registry)
963 },
964 move |data, value, serialzier, initialized, registry| {
965 deserialize_to(
966 data.cast::<T>().as_mut().unwrap(),
967 value,
968 serialzier,
969 initialized,
970 registry,
971 )
972 },
973 );
974 }
975 }
976
977 pub unsafe fn register_raw(
979 &mut self,
980 type_hash: TypeHash,
981 serialize_from: impl Fn(*const u8, &Self, &Registry) -> Result<Intermediate, Box<dyn Error>>
982 + Send
983 + Sync
984 + 'static,
985 deserialize_to: impl Fn(
986 *mut u8,
987 &Intermediate,
988 &Self,
989 bool,
990 &Registry,
991 ) -> Result<(), Box<dyn Error>>
992 + Send
993 + Sync
994 + 'static,
995 ) {
996 self.mapping.insert(
997 type_hash,
998 Serializer {
999 serialize_from: Box::new(serialize_from),
1000 deserialize_to: Box::new(deserialize_to),
1001 },
1002 );
1003 }
1004
1005 pub fn unregister<T>(&mut self) {
1006 self.unregister_raw(TypeHash::of::<T>());
1007 }
1008
1009 pub fn unregister_raw(&mut self, type_hash: TypeHash) {
1010 self.mapping.remove(&type_hash);
1011 }
1012
1013 pub fn serialize_from<T>(
1014 &self,
1015 data: &T,
1016 registry: &Registry,
1017 ) -> Result<Intermediate, Box<dyn Error>> {
1018 unsafe {
1019 let type_hash = TypeHash::of::<T>();
1020 self.dynamic_serialize_from(type_hash, data as *const T as *const u8, registry)
1021 .map_err(|error| format!("{}. Type: {}", error, std::any::type_name::<T>()).into())
1022 }
1023 }
1024
1025 pub unsafe fn dynamic_serialize_from(
1027 &self,
1028 type_hash: TypeHash,
1029 data: *const u8,
1030 registry: &Registry,
1031 ) -> Result<Intermediate, Box<dyn Error>> {
1032 if let Some(serializer) = self.mapping.get(&type_hash) {
1033 return (serializer.serialize_from)(data, self, registry);
1034 }
1035 Err("Type does not exist in serialization registry".into())
1036 }
1037
1038 pub fn deserialize_to<T: Default>(
1039 &self,
1040 value: &Intermediate,
1041 registry: &Registry,
1042 ) -> Result<T, Box<dyn Error>> {
1043 let mut result = T::default();
1044 unsafe {
1045 self.dynamic_deserialize_to(
1046 TypeHash::of::<T>(),
1047 &mut result as *mut T as *mut u8,
1048 value,
1049 true,
1050 registry,
1051 )
1052 .map_err(|error| format!("{}. Type: {}", error, std::any::type_name::<T>()))?;
1053 }
1054 Ok(result)
1055 }
1056
1057 pub fn deserialize_into<T>(
1058 &self,
1059 result: &mut T,
1060 value: &Intermediate,
1061 registry: &Registry,
1062 ) -> Result<(), Box<dyn Error>> {
1063 unsafe {
1064 self.dynamic_deserialize_to(
1065 TypeHash::of::<T>(),
1066 result as *mut T as *mut u8,
1067 value,
1068 true,
1069 registry,
1070 )
1071 .map_err(|error| format!("{}. Type: {}", error, std::any::type_name::<T>()))?;
1072 }
1073 Ok(())
1074 }
1075
1076 pub unsafe fn dynamic_deserialize_to(
1078 &self,
1079 type_hash: TypeHash,
1080 data: *mut u8,
1081 value: &Intermediate,
1082 data_initialized: bool,
1083 registry: &Registry,
1084 ) -> Result<(), Box<dyn Error>> {
1085 if let Some(serializer) = self.mapping.get(&type_hash) {
1086 (serializer.deserialize_to)(data, value, self, data_initialized, registry)?;
1087 return Ok(());
1088 }
1089 Err("Type not existent in serialization registry".into())
1090 }
1091}
1092
1093#[cfg(test)]
1094mod tests {
1095 use super::*;
1096 use intuicio_core::{IntuicioEnum, IntuicioStruct, registry::Registry};
1097 use intuicio_derive::{IntuicioEnum, IntuicioStruct};
1098 use serde::Deserialize;
1099
1100 #[derive(IntuicioEnum, Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
1101 #[repr(u8)]
1102 enum Skill {
1103 #[default]
1104 Brain,
1105 Muscles(bool),
1106 Magic {
1107 power: i32,
1108 },
1109 }
1110
1111 #[derive(IntuicioStruct, Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
1112 struct Person {
1113 name: String,
1114 age: usize,
1115 skill: Skill,
1116 }
1117
1118 #[derive(IntuicioStruct)]
1119 struct Wrapper {
1120 object: DynamicManaged,
1121 }
1122
1123 impl Default for Wrapper {
1124 fn default() -> Self {
1125 Self {
1126 object: DynamicManaged::new(()).unwrap(),
1127 }
1128 }
1129 }
1130
1131 #[test]
1132 fn test_serde_serialization() {
1133 let registry = Registry::default().with_basic_types();
1134 let serialization = SerializationRegistry::default()
1135 .with_basic_types()
1136 .with_serde::<Skill>()
1137 .with_serde::<Person>();
1138
1139 let data = Person {
1140 name: "Grumpy".to_owned(),
1141 age: 24,
1142 skill: Skill::Magic { power: 42 },
1143 };
1144 let serialized = serialization.serialize_from(&data, ®istry).unwrap();
1145 let data2 = serialization
1146 .deserialize_to::<Person>(&serialized, ®istry)
1147 .unwrap();
1148 assert_eq!(data, data2);
1149 }
1150
1151 #[test]
1152 fn test_reflection_serialization() {
1153 let mut registry = Registry::default().with_basic_types();
1154 let skill_type = registry.add_type(Skill::define_enum(®istry));
1155 let person_type = registry.add_type(Person::define_struct(®istry));
1156 let serialization = SerializationRegistry::default()
1157 .with_basic_types()
1158 .with_reflection(skill_type)
1159 .with_reflection(person_type);
1160
1161 let data = Person {
1162 name: "Grumpy".to_owned(),
1163 age: 24,
1164 skill: Skill::Magic { power: 42 },
1165 };
1166 let serialized = serialization.serialize_from(&data, ®istry).unwrap();
1167 let data2 = serialization
1168 .deserialize_to::<Person>(&serialized, ®istry)
1169 .unwrap();
1170 assert_eq!(data, data2);
1171 }
1172
1173 #[test]
1174 fn test_type_erased_serialization() {
1175 let mut registry = Registry::default().with_basic_types().with_erased_types();
1176 registry.add_type(Skill::define_enum(®istry));
1177 registry.add_type(Person::define_struct(®istry));
1178 let wrapper_type = registry.add_type(Wrapper::define_struct(®istry));
1179 let serialization = SerializationRegistry::default()
1180 .with_basic_types()
1181 .with_serde::<Skill>()
1182 .with_serde::<Person>()
1183 .with_reflection(wrapper_type)
1184 .with_erased_types();
1185
1186 let data = Wrapper {
1187 object: DynamicManaged::new(Person {
1188 name: "Grumpy".to_owned(),
1189 age: 24,
1190 skill: Skill::Magic { power: 42 },
1191 })
1192 .unwrap(),
1193 };
1194 let serialized = serialization.serialize_from(&data, ®istry).unwrap();
1195 let data2 = serialization
1196 .deserialize_to::<Wrapper>(&serialized, ®istry)
1197 .unwrap();
1198 let data = data.object.consume::<Person>().ok().unwrap();
1199 let data2 = data2.object.consume::<Person>().ok().unwrap();
1200 assert_eq!(data, data2);
1201 }
1202}