props: move property serde impls to their own mod
This commit is contained in:
		
							parent
							
								
									76adb888d3
								
							
						
					
					
						commit
						d86d3ddcbc
					
				| @ -203,7 +203,7 @@ pub fn derive_properties(input: TokenStream) -> TokenStream { | ||||
|             } | ||||
| 
 | ||||
|             fn serializable(&self) -> #bevy_property_path::Serializable { | ||||
|                 #bevy_property_path::Serializable::Owned(Box::new(#bevy_property_path::MapSerializer::new(self))) | ||||
|                 #bevy_property_path::Serializable::Owned(Box::new(#bevy_property_path::property_serde::MapSerializer::new(self))) | ||||
|             } | ||||
|         } | ||||
|     }) | ||||
|  | ||||
| @ -1,14 +1,5 @@ | ||||
| use crate::{ | ||||
|     Properties, PropertiesType, Property, PropertyIter, | ||||
|     PropertyTypeRegistry, Serializable, | ||||
| }; | ||||
| use de::SeqAccess; | ||||
| use serde::{ | ||||
|     de::{self, DeserializeSeed, MapAccess, Visitor}, | ||||
|     ser::{SerializeMap, SerializeSeq}, | ||||
|     Serialize, | ||||
| }; | ||||
| use std::{any::Any, borrow::Cow, cell::RefCell, collections::HashMap, rc::Rc}; | ||||
| use crate::{Properties, PropertiesType, Property, PropertyIter, Serializable}; | ||||
| use std::{any::Any, borrow::Cow, collections::HashMap}; | ||||
| 
 | ||||
| pub struct DynamicProperties { | ||||
|     pub type_name: String, | ||||
| @ -188,372 +179,3 @@ impl Property for DynamicProperties { | ||||
|         Serializable::Borrowed(self) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Serialize for DynamicProperties { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         match self.properties_type { | ||||
|             PropertiesType::Map => MapSerializer::new(self).serialize(serializer), | ||||
|             PropertiesType::Seq => SeqSerializer::new(self).serialize(serializer), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct MapSerializer<'a> { | ||||
|     pub properties: &'a dyn Properties, | ||||
| } | ||||
| 
 | ||||
| impl<'a> MapSerializer<'a> { | ||||
|     pub fn new(properties: &'a dyn Properties) -> Self { | ||||
|         MapSerializer { properties } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for MapSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_map(Some(self.properties.prop_len()))?; | ||||
|         state.serialize_entry("type", self.properties.type_name())?; | ||||
|         for (index, property) in self.properties.iter_props().enumerate() { | ||||
|             let name = self.properties.prop_name(index).unwrap(); | ||||
|             if property.is_sequence() { | ||||
|                 state.serialize_entry(name, &SeqSerializer { property })?; | ||||
|             } else { | ||||
|                 state.serialize_entry(name, property.serializable().borrow())?; | ||||
|             } | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct SeqSerializer<'a> { | ||||
|     pub property: &'a dyn Property, | ||||
| } | ||||
| 
 | ||||
| impl<'a> SeqSerializer<'a> { | ||||
|     pub fn new(property: &'a dyn Property) -> Self { | ||||
|         SeqSerializer { property } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for SeqSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_map(Some(2))?; | ||||
|         if let Some(properties) = self.property.as_properties() { | ||||
|             state.serialize_entry("seq_type", self.property.type_name())?; | ||||
|             state.serialize_entry("data", &PropertiesSeqSerializer { properties })?; | ||||
|         } else { | ||||
|             state.serialize_entry("seq_value_type", self.property.type_name())?; | ||||
|             state.serialize_entry("data", self.property.serializable().borrow())?; | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropertiesSeqSerializer<'a> { | ||||
|     pub properties: &'a dyn Properties, | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for PropertiesSeqSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_seq(Some(self.properties.prop_len()))?; | ||||
|         for prop in self.properties.iter_props() { | ||||
|             state.serialize_element(prop.serializable().borrow())?; | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct DynamicPropertiesDeserializer<'a> { | ||||
|     pub registry: &'a PropertyTypeRegistry, | ||||
|     pub current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for DynamicPropertiesDeserializer<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_map(DynamicPropertyMapVisiter { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct DynamicPropertyMapVisiter<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for DynamicPropertyMapVisiter<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("properties map") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: MapAccess<'de>, | ||||
|     { | ||||
|         visit_map(map, self.registry, self.current_type_name) | ||||
|     } | ||||
| } | ||||
| pub struct PropertyDeserializer<'a> { | ||||
|     pub registry: &'a PropertyTypeRegistry, | ||||
|     pub current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_any(AnyPropVisiter { | ||||
|             property_type_registry: self.registry, | ||||
|             current_type_name: self.current_type_name, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropSeqDeserializer<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_seq(PropSeqVisiter { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name.clone(), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropSeqVisiter<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("property value") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: SeqAccess<'de>, | ||||
|     { | ||||
|         let mut dynamic_properties = DynamicProperties::seq(); | ||||
|         while let Some(prop) = seq.next_element_seed(PropertyDeserializer { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name.clone(), | ||||
|         })? { | ||||
|             dynamic_properties.push(prop, None); | ||||
|         } | ||||
|         Ok(dynamic_properties) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct MapValueDeserializer<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         if self.current_type_name.borrow().is_some() { | ||||
|             let registration = { | ||||
|                 let current_type_name = self.current_type_name.borrow(); | ||||
|                 let type_name = current_type_name.as_ref().unwrap(); | ||||
|                 self.registry | ||||
|                     .get_short(type_name) | ||||
|                     .ok_or_else(|| { | ||||
|                         de::Error::custom(format!("TypeRegistration is missing for {}", type_name)) | ||||
|                     })? | ||||
|             }; | ||||
|             let mut erased = erased_serde::Deserializer::erase(deserializer); | ||||
|             (registration.deserialize)(&mut erased, self.registry) | ||||
|                 .map_err(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom) | ||||
|         } else { | ||||
|             deserializer.deserialize_any(AnyPropVisiter { | ||||
|                 property_type_registry: self.registry, | ||||
|                 current_type_name: self.current_type_name, | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct AnyPropVisiter<'a> { | ||||
|     property_type_registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("property value") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_string<E>(self, v: String) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v.to_string())) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: MapAccess<'de>, | ||||
|     { | ||||
|         Ok(Box::new(visit_map(map, self.property_type_registry, self.current_type_name)?)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn visit_map<'a, 'de, V>( | ||||
|     mut map: V, | ||||
|     property_type_registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| ) -> Result<DynamicProperties, V::Error> | ||||
| where | ||||
|     V: MapAccess<'de>, | ||||
| { | ||||
|     let mut dynamic_properties = DynamicProperties::map(); | ||||
|     let mut type_name: Option<String> = None; | ||||
|     let mut is_seq = false; | ||||
|     // TODO: support seq_value_type
 | ||||
|     while let Some(key) = map.next_key::<String>()? { | ||||
|         if key == "type" { | ||||
|             type_name = Some(map.next_value()?); | ||||
|         } else if key == "seq_type" { | ||||
|             type_name = Some(map.next_value()?); | ||||
|             is_seq = true; | ||||
|         } else if is_seq { | ||||
|             if key != "data" { | ||||
|                 return Err(de::Error::custom( | ||||
|                     "seq_type must be immediately followed by a data field", | ||||
|                 )); | ||||
|             } | ||||
|             dynamic_properties = map.next_value_seed(PropSeqDeserializer { | ||||
|                 registry: property_type_registry, | ||||
|                 current_type_name: current_type_name.clone(), | ||||
|             })?; | ||||
|             break; | ||||
|         } else { | ||||
|             let prop = map.next_value_seed(MapValueDeserializer { | ||||
|                 registry: property_type_registry, | ||||
|                 current_type_name: current_type_name.clone(), | ||||
|             })?; | ||||
|             dynamic_properties.set_box(&key, prop); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let type_name = type_name.ok_or_else(|| de::Error::missing_field("type"))?; | ||||
|     dynamic_properties.type_name = type_name.to_string(); | ||||
|     Ok(dynamic_properties) | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter, SeqSerializer, Serializable}; | ||||
| use crate::{impl_property, Properties, PropertiesType, Property, PropertyIter, Serializable, property_serde::SeqSerializer}; | ||||
| use serde::{Serialize, Deserialize}; | ||||
| use std::{ | ||||
|     any::Any, | ||||
|  | ||||
| @ -7,6 +7,7 @@ mod impl_property_smallvec; | ||||
| mod impl_property_glam; | ||||
| mod impl_property_legion; | ||||
| pub mod ron; | ||||
| pub mod property_serde; | ||||
| 
 | ||||
| pub use property::*; | ||||
| pub use properties::*; | ||||
|  | ||||
							
								
								
									
										380
									
								
								crates/bevy_property/src/property_serde.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								crates/bevy_property/src/property_serde.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,380 @@ | ||||
| use crate::{DynamicProperties, Properties, PropertiesType, Property, PropertyTypeRegistry}; | ||||
| use de::SeqAccess; | ||||
| use serde::{ | ||||
|     de::{self, DeserializeSeed, MapAccess, Visitor}, | ||||
|     ser::{SerializeMap, SerializeSeq}, | ||||
|     Serialize, | ||||
| }; | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| 
 | ||||
| impl Serialize for DynamicProperties { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         match self.properties_type { | ||||
|             PropertiesType::Map => MapSerializer::new(self).serialize(serializer), | ||||
|             PropertiesType::Seq => SeqSerializer::new(self).serialize(serializer), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct DynamicPropertiesDeserializer<'a> { | ||||
|     pub registry: &'a PropertyTypeRegistry, | ||||
|     pub current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for DynamicPropertiesDeserializer<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_map(DynamicPropertyMapVisiter { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct DynamicPropertyMapVisiter<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for DynamicPropertyMapVisiter<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("properties map") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: MapAccess<'de>, | ||||
|     { | ||||
|         visit_map(map, self.registry, self.current_type_name) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct MapSerializer<'a> { | ||||
|     pub properties: &'a dyn Properties, | ||||
| } | ||||
| 
 | ||||
| impl<'a> MapSerializer<'a> { | ||||
|     pub fn new(properties: &'a dyn Properties) -> Self { | ||||
|         MapSerializer { properties } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for MapSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_map(Some(self.properties.prop_len()))?; | ||||
|         state.serialize_entry("type", self.properties.type_name())?; | ||||
|         for (index, property) in self.properties.iter_props().enumerate() { | ||||
|             let name = self.properties.prop_name(index).unwrap(); | ||||
|             if property.is_sequence() { | ||||
|                 state.serialize_entry(name, &SeqSerializer { property })?; | ||||
|             } else { | ||||
|                 state.serialize_entry(name, property.serializable().borrow())?; | ||||
|             } | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct SeqSerializer<'a> { | ||||
|     pub property: &'a dyn Property, | ||||
| } | ||||
| 
 | ||||
| impl<'a> SeqSerializer<'a> { | ||||
|     pub fn new(property: &'a dyn Property) -> Self { | ||||
|         SeqSerializer { property } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for SeqSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_map(Some(2))?; | ||||
|         if let Some(properties) = self.property.as_properties() { | ||||
|             state.serialize_entry("seq_type", self.property.type_name())?; | ||||
|             state.serialize_entry("data", &PropertiesSeqSerializer { properties })?; | ||||
|         } else { | ||||
|             state.serialize_entry("seq_value_type", self.property.type_name())?; | ||||
|             state.serialize_entry("data", self.property.serializable().borrow())?; | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropertiesSeqSerializer<'a> { | ||||
|     pub properties: &'a dyn Properties, | ||||
| } | ||||
| 
 | ||||
| impl<'a> Serialize for PropertiesSeqSerializer<'a> { | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
|         S: serde::Serializer, | ||||
|     { | ||||
|         let mut state = serializer.serialize_seq(Some(self.properties.prop_len()))?; | ||||
|         for prop in self.properties.iter_props() { | ||||
|             state.serialize_element(prop.serializable().borrow())?; | ||||
|         } | ||||
|         state.end() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropertyDeserializer<'a> { | ||||
|     pub registry: &'a PropertyTypeRegistry, | ||||
|     pub current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_any(AnyPropVisiter { | ||||
|             property_type_registry: self.registry, | ||||
|             current_type_name: self.current_type_name, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropSeqDeserializer<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for PropSeqDeserializer<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         deserializer.deserialize_seq(PropSeqVisiter { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name.clone(), | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct PropSeqVisiter<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for PropSeqVisiter<'a> { | ||||
|     type Value = DynamicProperties; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("property value") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: SeqAccess<'de>, | ||||
|     { | ||||
|         let mut dynamic_properties = DynamicProperties::seq(); | ||||
|         while let Some(prop) = seq.next_element_seed(PropertyDeserializer { | ||||
|             registry: self.registry, | ||||
|             current_type_name: self.current_type_name.clone(), | ||||
|         })? { | ||||
|             dynamic_properties.push(prop, None); | ||||
|         } | ||||
|         Ok(dynamic_properties) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct MapValueDeserializer<'a> { | ||||
|     registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> DeserializeSeed<'de> for MapValueDeserializer<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> | ||||
|     where | ||||
|         D: serde::Deserializer<'de>, | ||||
|     { | ||||
|         if self.current_type_name.borrow().is_some() { | ||||
|             let registration = { | ||||
|                 let current_type_name = self.current_type_name.borrow(); | ||||
|                 let type_name = current_type_name.as_ref().unwrap(); | ||||
|                 self.registry.get_short(type_name).ok_or_else(|| { | ||||
|                     de::Error::custom(format!("TypeRegistration is missing for {}", type_name)) | ||||
|                 })? | ||||
|             }; | ||||
|             let mut erased = erased_serde::Deserializer::erase(deserializer); | ||||
|             (registration.deserialize)(&mut erased, self.registry) | ||||
|                 .map_err(<<D as serde::Deserializer<'de>>::Error as serde::de::Error>::custom) | ||||
|         } else { | ||||
|             deserializer.deserialize_any(AnyPropVisiter { | ||||
|                 property_type_registry: self.registry, | ||||
|                 current_type_name: self.current_type_name, | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct AnyPropVisiter<'a> { | ||||
|     property_type_registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| } | ||||
| 
 | ||||
| impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> { | ||||
|     type Value = Box<dyn Property>; | ||||
|     fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         formatter.write_str("property value") | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_string<E>(self, v: String) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v)) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> | ||||
|     where | ||||
|         E: de::Error, | ||||
|     { | ||||
|         Ok(Box::new(v.to_string())) | ||||
|     } | ||||
| 
 | ||||
|     fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error> | ||||
|     where | ||||
|         V: MapAccess<'de>, | ||||
|     { | ||||
|         Ok(Box::new(visit_map( | ||||
|             map, | ||||
|             self.property_type_registry, | ||||
|             self.current_type_name, | ||||
|         )?)) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn visit_map<'a, 'de, V>( | ||||
|     mut map: V, | ||||
|     property_type_registry: &'a PropertyTypeRegistry, | ||||
|     current_type_name: Rc<RefCell<Option<String>>>, | ||||
| ) -> Result<DynamicProperties, V::Error> | ||||
| where | ||||
|     V: MapAccess<'de>, | ||||
| { | ||||
|     let mut dynamic_properties = DynamicProperties::map(); | ||||
|     let mut type_name: Option<String> = None; | ||||
|     let mut is_seq = false; | ||||
|     // TODO: support seq_value_type
 | ||||
|     while let Some(key) = map.next_key::<String>()? { | ||||
|         if key == "type" { | ||||
|             type_name = Some(map.next_value()?); | ||||
|         } else if key == "seq_type" { | ||||
|             type_name = Some(map.next_value()?); | ||||
|             is_seq = true; | ||||
|         } else if is_seq { | ||||
|             if key != "data" { | ||||
|                 return Err(de::Error::custom( | ||||
|                     "seq_type must be immediately followed by a data field", | ||||
|                 )); | ||||
|             } | ||||
|             dynamic_properties = map.next_value_seed(PropSeqDeserializer { | ||||
|                 registry: property_type_registry, | ||||
|                 current_type_name: current_type_name.clone(), | ||||
|             })?; | ||||
|             break; | ||||
|         } else { | ||||
|             let prop = map.next_value_seed(MapValueDeserializer { | ||||
|                 registry: property_type_registry, | ||||
|                 current_type_name: current_type_name.clone(), | ||||
|             })?; | ||||
|             dynamic_properties.set_box(&key, prop); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let type_name = type_name.ok_or_else(|| de::Error::missing_field("type"))?; | ||||
|     dynamic_properties.type_name = type_name.to_string(); | ||||
|     Ok(dynamic_properties) | ||||
| } | ||||
| @ -1,9 +1,14 @@ | ||||
| use crate::{ | ||||
|     property_serde::DynamicPropertiesDeserializer, DynamicProperties, PropertyTypeRegistry, | ||||
| }; | ||||
| use ron::de::Deserializer; | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| use crate::{DynamicPropertiesDeserializer, PropertyTypeRegistry, DynamicProperties}; | ||||
| use serde::de::DeserializeSeed; | ||||
| use std::{cell::RefCell, rc::Rc}; | ||||
| 
 | ||||
| pub fn deserialize_dynamic_properties(ron_string: &str, property_type_registry: &PropertyTypeRegistry) -> Result<DynamicProperties, ron::Error> { | ||||
| pub fn deserialize_dynamic_properties( | ||||
|     ron_string: &str, | ||||
|     property_type_registry: &PropertyTypeRegistry, | ||||
| ) -> Result<DynamicProperties, ron::Error> { | ||||
|     let mut deserializer = Deserializer::from_str(&ron_string).unwrap(); | ||||
|     let last_type_name = Rc::new(RefCell::new(None)); | ||||
|     let mut callback = |ident: &Option<&[u8]>| { | ||||
| @ -16,4 +21,4 @@ pub fn deserialize_dynamic_properties(ron_string: &str, property_type_registry: | ||||
|         registry: &property_type_registry, | ||||
|     }; | ||||
|     dynamic_properties_deserializer.deserialize(&mut deserializer) | ||||
| } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| use crate::{Entity, Scene}; | ||||
| use anyhow::Result; | ||||
| use bevy_property::{DynamicProperties, DynamicPropertiesDeserializer, PropertyTypeRegistry}; | ||||
| use bevy_property::{DynamicProperties, PropertyTypeRegistry, property_serde::DynamicPropertiesDeserializer}; | ||||
| use serde::{ | ||||
|     de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor}, | ||||
|     Deserialize, Serialize, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson