bevy_reflect/serde/
type_data.rs

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