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