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}