1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use crate::Reflect;
use bevy_utils::hashbrown::hash_map::Iter;
use bevy_utils::HashMap;

/// Contains data relevant to the automatic reflect powered (de)serialization of a type.
#[derive(Debug, Clone)]
pub struct SerializationData {
    skipped_fields: HashMap<usize, SkippedField>,
}

impl SerializationData {
    /// Creates a new `SerializationData` instance with the given skipped fields.
    ///
    /// # Arguments
    ///
    /// * `skipped_iter`: The iterator of field indices to be skipped during (de)serialization.
    ///                   Indices are assigned only to reflected fields.
    ///                   Ignored fields (i.e. those marked `#[reflect(ignore)]`) are implicitly skipped
    ///                   and do not need to be included in this iterator.
    pub fn new<I: Iterator<Item = (usize, SkippedField)>>(skipped_iter: I) -> Self {
        Self {
            skipped_fields: skipped_iter.collect(),
        }
    }
    /// Returns true if the given index corresponds to a field meant to be skipped during (de)serialization.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::any::TypeId;
    /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
    /// #[derive(Reflect)]
    /// struct MyStruct {
    ///   serialize_me: i32,
    ///   #[reflect(skip_serializing)]
    ///   skip_me: i32
    /// }
    ///
    /// let mut registry = TypeRegistry::new();
    /// registry.register::<MyStruct>();
    ///
    /// let my_struct = MyStruct {
    ///   serialize_me: 123,
    ///   skip_me: 321,
    /// };
    ///
    /// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
    ///
    /// for (idx, field) in my_struct.iter_fields().enumerate(){
    ///   if serialization_data.is_field_skipped(idx) {
    ///     // Skipped!
    ///     assert_eq!(1, idx);
    ///   } else {
    ///     // Not Skipped!
    ///     assert_eq!(0, idx);
    ///   }
    /// }
    /// ```
    pub fn is_field_skipped(&self, index: usize) -> bool {
        self.skipped_fields.contains_key(&index)
    }

    /// Generates a default instance of the skipped field at the given index.
    ///
    /// Returns `None` if the field is not skipped.
    ///
    /// # Example
    ///
    /// ```
    /// # use std::any::TypeId;
    /// # use bevy_reflect::{Reflect, Struct, TypeRegistry, serde::SerializationData};
    /// #[derive(Reflect)]
    /// struct MyStruct {
    ///   serialize_me: i32,
    ///   #[reflect(skip_serializing)]
    ///   #[reflect(default = "skip_me_default")]
    ///   skip_me: i32
    /// }
    ///
    /// fn skip_me_default() -> i32 {
    ///   789
    /// }
    ///
    /// let mut registry = TypeRegistry::new();
    /// registry.register::<MyStruct>();
    ///
    /// let serialization_data = registry.get_type_data::<SerializationData>(TypeId::of::<MyStruct>()).unwrap();
    /// assert_eq!(789, serialization_data.generate_default(1).unwrap().take::<i32>().unwrap());
    /// ```
    pub fn generate_default(&self, index: usize) -> Option<Box<dyn Reflect>> {
        self.skipped_fields
            .get(&index)
            .map(|field| field.generate_default())
    }

    /// Returns the number of skipped fields.
    pub fn len(&self) -> usize {
        self.skipped_fields.len()
    }

    /// Returns true if there are no skipped fields.
    pub fn is_empty(&self) -> bool {
        self.skipped_fields.is_empty()
    }

    /// Returns an iterator over the skipped fields.
    ///
    /// Each item in the iterator is a tuple containing:
    /// 1. The reflected index of the field
    /// 2. The (de)serialization metadata of the field  
    pub fn iter_skipped(&self) -> Iter<'_, usize, SkippedField> {
        self.skipped_fields.iter()
    }
}

/// Data needed for (de)serialization of a skipped field.
#[derive(Debug, Clone)]
pub struct SkippedField {
    default_fn: fn() -> Box<dyn Reflect>,
}

impl SkippedField {
    /// Create a new `SkippedField`.
    ///
    /// # Arguments
    ///
    /// * `default_fn`: A function pointer used to generate a default instance of the field.
    pub fn new(default_fn: fn() -> Box<dyn Reflect>) -> Self {
        Self { default_fn }
    }

    /// Generates a default instance of the field.
    pub fn generate_default(&self) -> Box<dyn Reflect> {
        (self.default_fn)()
    }
}