|  | 
| 1 | 1 | mod de; | 
|  | 2 | +mod deserialize_reflect; | 
| 2 | 3 | mod ser; | 
| 3 | 4 | mod type_data; | 
| 4 | 5 | 
 | 
| 5 | 6 | pub use de::*; | 
|  | 7 | +pub use deserialize_reflect::*; | 
| 6 | 8 | pub use ser::*; | 
| 7 | 9 | pub use type_data::*; | 
| 8 | 10 | 
 | 
| 9 | 11 | #[cfg(test)] | 
| 10 | 12 | mod tests { | 
| 11 |  | -    use crate::{self as bevy_reflect, DynamicTupleStruct}; | 
|  | 13 | +    use crate::{self as bevy_reflect, DynamicTupleStruct, ReflectDeserialize, Struct}; | 
| 12 | 14 |     use crate::{ | 
| 13 |  | -        serde::{ReflectSerializer, UntypedReflectDeserializer}, | 
|  | 15 | +        serde::{ | 
|  | 16 | +            DeserializeReflect, ReflectDeserializeReflect, ReflectSerializer, | 
|  | 17 | +            TypedReflectDeserializer, UntypedReflectDeserializer, | 
|  | 18 | +        }, | 
| 14 | 19 |         type_registry::TypeRegistry, | 
| 15 | 20 |         DynamicStruct, Reflect, | 
| 16 | 21 |     }; | 
| 17 |  | -    use serde::de::DeserializeSeed; | 
|  | 22 | +    use bevy_reflect_derive::FromReflect; | 
|  | 23 | +    use serde::de::{DeserializeSeed, SeqAccess, Visitor}; | 
|  | 24 | +    use serde::{Deserialize, Deserializer}; | 
|  | 25 | +    use std::fmt::Formatter; | 
| 18 | 26 | 
 | 
| 19 | 27 |     #[test] | 
| 20 | 28 |     fn test_serialization_struct() { | 
| @@ -104,4 +112,138 @@ mod tests { | 
| 104 | 112 |         let serializer = ReflectSerializer::new(&value, ®istry); | 
| 105 | 113 |         ron::ser::to_string(&serializer).unwrap(); | 
| 106 | 114 |     } | 
|  | 115 | + | 
|  | 116 | +    #[test] | 
|  | 117 | +    fn should_deserialize_using_deserialize_reflect() { | 
|  | 118 | +        #[derive(Reflect, FromReflect, PartialEq, Debug, Deserialize)] | 
|  | 119 | +        #[reflect(Deserialize)] | 
|  | 120 | +        enum AnimalType { | 
|  | 121 | +            Dog, | 
|  | 122 | +            Cat, | 
|  | 123 | +        } | 
|  | 124 | + | 
|  | 125 | +        #[derive(Reflect, FromReflect)] | 
|  | 126 | +        struct Dog { | 
|  | 127 | +            name: DogName, | 
|  | 128 | +        } | 
|  | 129 | + | 
|  | 130 | +        #[derive(Reflect, FromReflect)] | 
|  | 131 | +        enum DogName { | 
|  | 132 | +            Spot, | 
|  | 133 | +            Fido, | 
|  | 134 | +            Rex, | 
|  | 135 | +        } | 
|  | 136 | + | 
|  | 137 | +        #[derive(Reflect, FromReflect)] | 
|  | 138 | +        struct Cat { | 
|  | 139 | +            name: CatName, | 
|  | 140 | +        } | 
|  | 141 | + | 
|  | 142 | +        #[derive(Reflect, FromReflect)] | 
|  | 143 | +        enum CatName { | 
|  | 144 | +            Fluffy, | 
|  | 145 | +            Snowball, | 
|  | 146 | +            Luna, | 
|  | 147 | +        } | 
|  | 148 | + | 
|  | 149 | +        /// Pet is made up of two fields: the type of animal and the animal itself. | 
|  | 150 | +        /// | 
|  | 151 | +        /// This allows us to store a type-erased version of our pet, | 
|  | 152 | +        /// rather than having to define one like this: | 
|  | 153 | +        /// | 
|  | 154 | +        /// ``` | 
|  | 155 | +        /// # use bevy_reflect::prelude::Reflect; | 
|  | 156 | +        /// #[derive(Reflect)] | 
|  | 157 | +        /// struct Pet<T: Reflect>(T); | 
|  | 158 | +        /// ``` | 
|  | 159 | +        /// | 
|  | 160 | +        /// If we wanted to allow for deserialization of any type, | 
|  | 161 | +        /// we could replace `AnimalType` with a `String` containing the type name of the animal. | 
|  | 162 | +        #[derive(Reflect)] | 
|  | 163 | +        #[reflect(DeserializeReflect)] | 
|  | 164 | +        struct Pet(AnimalType, DynamicStruct); | 
|  | 165 | + | 
|  | 166 | +        impl<'de> DeserializeReflect<'de> for Pet { | 
|  | 167 | +            fn deserialize<D>(deserializer: D, registry: &TypeRegistry) -> Result<Self, D::Error> | 
|  | 168 | +            where | 
|  | 169 | +                D: Deserializer<'de>, | 
|  | 170 | +            { | 
|  | 171 | +                struct PetVisitor<'a> { | 
|  | 172 | +                    registry: &'a TypeRegistry, | 
|  | 173 | +                } | 
|  | 174 | +                impl<'a, 'de> Visitor<'de> for PetVisitor<'a> { | 
|  | 175 | +                    type Value = Pet; | 
|  | 176 | + | 
|  | 177 | +                    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { | 
|  | 178 | +                        write!(formatter, "a pet tuple struct") | 
|  | 179 | +                    } | 
|  | 180 | + | 
|  | 181 | +                    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> | 
|  | 182 | +                    where | 
|  | 183 | +                        A: SeqAccess<'de>, | 
|  | 184 | +                    { | 
|  | 185 | +                        let kind = seq.next_element::<AnimalType>()?.unwrap(); | 
|  | 186 | +                        match kind { | 
|  | 187 | +                            AnimalType::Cat => { | 
|  | 188 | +                                let cat = seq | 
|  | 189 | +                                    .next_element_seed(TypedReflectDeserializer::of::<Cat>( | 
|  | 190 | +                                        self.registry, | 
|  | 191 | +                                    ))? | 
|  | 192 | +                                    .unwrap() | 
|  | 193 | +                                    .take::<DynamicStruct>() | 
|  | 194 | +                                    .unwrap(); | 
|  | 195 | +                                Ok(Pet(kind, cat)) | 
|  | 196 | +                            } | 
|  | 197 | +                            AnimalType::Dog => { | 
|  | 198 | +                                let dog = seq | 
|  | 199 | +                                    .next_element_seed(TypedReflectDeserializer::of::<Dog>( | 
|  | 200 | +                                        self.registry, | 
|  | 201 | +                                    ))? | 
|  | 202 | +                                    .unwrap() | 
|  | 203 | +                                    .take::<DynamicStruct>() | 
|  | 204 | +                                    .unwrap(); | 
|  | 205 | +                                Ok(Pet(kind, dog)) | 
|  | 206 | +                            } | 
|  | 207 | +                        } | 
|  | 208 | +                    } | 
|  | 209 | +                } | 
|  | 210 | + | 
|  | 211 | +                deserializer.deserialize_tuple_struct("Pet", 1, PetVisitor { registry }) | 
|  | 212 | +            } | 
|  | 213 | +        } | 
|  | 214 | + | 
|  | 215 | +        let mut registry = TypeRegistry::default(); | 
|  | 216 | +        registry.register::<Pet>(); | 
|  | 217 | +        registry.register::<AnimalType>(); | 
|  | 218 | +        registry.register::<Dog>(); | 
|  | 219 | +        registry.register::<DogName>(); | 
|  | 220 | +        registry.register::<Cat>(); | 
|  | 221 | +        registry.register::<CatName>(); | 
|  | 222 | + | 
|  | 223 | +        let pet = Pet( | 
|  | 224 | +            AnimalType::Cat, | 
|  | 225 | +            Cat { | 
|  | 226 | +                name: CatName::Fluffy, | 
|  | 227 | +            } | 
|  | 228 | +            .clone_dynamic(), | 
|  | 229 | +        ); | 
|  | 230 | + | 
|  | 231 | +        let serializer = ReflectSerializer::new(&pet, ®istry); | 
|  | 232 | +        let serialized = ron::ser::to_string(&serializer).unwrap(); | 
|  | 233 | + | 
|  | 234 | +        let expected = r#"{"bevy_reflect::serde::tests::should_deserialize_using_deserialize_reflect::Pet":(Cat,(name:Fluffy))}"#; | 
|  | 235 | + | 
|  | 236 | +        assert_eq!(expected, serialized); | 
|  | 237 | + | 
|  | 238 | +        let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap(); | 
|  | 239 | +        let reflect_deserializer = UntypedReflectDeserializer::new(®istry); | 
|  | 240 | +        let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); | 
|  | 241 | +        let deserialized = value.take::<Pet>().unwrap(); | 
|  | 242 | + | 
|  | 243 | +        assert_eq!(pet.0, deserialized.0); | 
|  | 244 | +        assert!(pet | 
|  | 245 | +            .1 | 
|  | 246 | +            .reflect_partial_eq(&deserialized.1) | 
|  | 247 | +            .unwrap_or_default()); | 
|  | 248 | +    } | 
| 107 | 249 | } | 
0 commit comments