bevy_reflect/serde/type_data.rs
1use crate::Reflect;
2use alloc::boxed::Box;
3use bevy_platform::collections::{hash_map::Iter, HashMap};
4
5/// Contains data relevant to the automatic reflect powered (de)serialization of a type.
6#[derive(Debug, Clone)]
7pub struct SerializationData {
8 skipped_fields: HashMap<usize, SkippedField>,
9}
10
11impl SerializationData {
12 /// Creates a new `SerializationData` instance with the given skipped fields.
13 ///
14 /// # Arguments
15 ///
16 /// * `skipped_iter`: The iterator of field indices to be skipped during (de)serialization.
17 /// Indices are assigned only to reflected fields.
18 /// Ignored fields (i.e. those marked `#[reflect(ignore)]`) are implicitly skipped
19 /// and do not need to be included in this iterator.
20 pub fn new<I: Iterator<Item = (usize, SkippedField)>>(skipped_iter: I) -> Self {
21 Self {
22 skipped_fields: skipped_iter.collect(),
23 }
24 }
25 /// Returns true if the given index corresponds to a field meant to be skipped during (de)serialization.
26 ///
27 /// # Example
28 ///
29 /// ```
30 /// # use core::any::TypeId;
31 /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
32 /// #[derive(Reflect)]
33 /// struct MyStruct {
34 /// serialize_me: i32,
35 /// #[reflect(skip_serializing)]
36 /// skip_me: i32
37 /// }
38 ///
39 /// let mut registry = TypeRegistry::new();
40 /// registry.register::<MyStruct>();
41 ///
42 /// let my_struct = MyStruct {
43 /// serialize_me: 123,
44 /// skip_me: 321,
45 /// };
46 ///
47 /// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
48 ///
49 /// for (idx, field) in my_struct.iter_fields().enumerate(){
50 /// if serialization_data.is_field_skipped(idx) {
51 /// // Skipped!
52 /// assert_eq!(1, idx);
53 /// } else {
54 /// // Not Skipped!
55 /// assert_eq!(0, idx);
56 /// }
57 /// }
58 /// ```
59 pub fn is_field_skipped(&self, index: usize) -> bool {
60 self.skipped_fields.contains_key(&index)
61 }
62
63 /// Generates a default instance of the skipped field at the given index.
64 ///
65 /// Returns `None` if the field is not skipped.
66 ///
67 /// # Example
68 ///
69 /// ```
70 /// # use core::any::TypeId;
71 /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
72 /// #[derive(Reflect)]
73 /// struct MyStruct {
74 /// serialize_me: i32,
75 /// #[reflect(skip_serializing)]
76 /// #[reflect(default = "skip_me_default")]
77 /// skip_me: i32
78 /// }
79 ///
80 /// fn skip_me_default() -> i32 {
81 /// 789
82 /// }
83 ///
84 /// let mut registry = TypeRegistry::new();
85 /// registry.register::<MyStruct>();
86 ///
87 /// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
88 /// assert_eq!(789, serialization_data.generate_default(1).unwrap().take::<i32>().unwrap());
89 /// ```
90 pub fn generate_default(&self, index: usize) -> Option<Box<dyn Reflect>> {
91 self.skipped_fields
92 .get(&index)
93 .map(SkippedField::generate_default)
94 }
95
96 /// Returns the number of skipped fields.
97 pub fn len(&self) -> usize {
98 self.skipped_fields.len()
99 }
100
101 /// Returns true if there are no skipped fields.
102 pub fn is_empty(&self) -> bool {
103 self.skipped_fields.is_empty()
104 }
105
106 /// Returns an iterator over the skipped fields.
107 ///
108 /// Each item in the iterator is a tuple containing:
109 /// 1. The reflected index of the field
110 /// 2. The (de)serialization metadata of the field
111 pub fn iter_skipped(&self) -> Iter<'_, usize, SkippedField> {
112 self.skipped_fields.iter()
113 }
114}
115
116/// Data needed for (de)serialization of a skipped field.
117#[derive(Debug, Clone)]
118pub struct SkippedField {
119 default_fn: fn() -> Box<dyn Reflect>,
120}
121
122impl SkippedField {
123 /// Create a new `SkippedField`.
124 ///
125 /// # Arguments
126 ///
127 /// * `default_fn`: A function pointer used to generate a default instance of the field.
128 pub fn new(default_fn: fn() -> Box<dyn Reflect>) -> Self {
129 Self { default_fn }
130 }
131
132 /// Generates a default instance of the field.
133 pub fn generate_default(&self) -> Box<dyn Reflect> {
134 (self.default_fn)()
135 }
136}