intuicio_framework_serde/
lib.rs

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    /// # Safety
974    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    /// # Safety
1022    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    /// # Safety
1073    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, &registry).unwrap();
1141        let data2 = serialization
1142            .deserialize_to::<Person>(&serialized, &registry)
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(&registry));
1151        let person_type = registry.add_type(Person::define_struct(&registry));
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, &registry).unwrap();
1163        let data2 = serialization
1164            .deserialize_to::<Person>(&serialized, &registry)
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(&registry));
1173        registry.add_type(Person::define_struct(&registry));
1174        let wrapper_type = registry.add_type(Wrapper::define_struct(&registry));
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, &registry).unwrap();
1191        let data2 = serialization
1192            .deserialize_to::<Wrapper>(&serialized, &registry)
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}