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}