props: fix dynamic property deserialization
This commit is contained in:
parent
563a6fc57c
commit
c03da2b728
@ -1,4 +1,4 @@
|
|||||||
use crate::{impl_property, Properties, Property, PropertyIter, property_serde::{Serializable, SeqSerializer}};
|
use crate::{impl_property, Properties, Property, PropertyIter, property_serde::{Serializable, SeqSerializer}, PropertyType};
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
@ -78,6 +78,10 @@ where
|
|||||||
fn serializable(&self) -> Serializable {
|
fn serializable(&self) -> Serializable {
|
||||||
Serializable::Owned(Box::new(SeqSerializer::new(self)))
|
Serializable::Owned(Box::new(SeqSerializer::new(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn property_type(&self) -> PropertyType {
|
||||||
|
PropertyType::Seq
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_property!(String);
|
impl_property!(String);
|
||||||
|
|||||||
@ -161,6 +161,51 @@ impl<'a> Serialize for SeqValueSerializer<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct DynamicPropertiesDeserializer<'a> {
|
||||||
|
registry: &'a PropertyTypeRegistry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DynamicPropertiesDeserializer<'a> {
|
||||||
|
pub fn new(registry: &'a PropertyTypeRegistry) -> Self {
|
||||||
|
DynamicPropertiesDeserializer { registry }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(DynamicPropertiesVisiter {
|
||||||
|
registry: self.registry,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DynamicPropertiesVisiter<'a> {
|
||||||
|
registry: &'a PropertyTypeRegistry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'de> Visitor<'de> for DynamicPropertiesVisiter<'a> {
|
||||||
|
type Value = DynamicProperties;
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("dynamic property")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
|
||||||
|
where
|
||||||
|
V: MapAccess<'de>,
|
||||||
|
{
|
||||||
|
match visit_map(map, self.registry)? {
|
||||||
|
DynamicPropertiesOrProperty::DynamicProperties(value) => Ok(value),
|
||||||
|
_ => Err(de::Error::custom("Expected DynamicProperties"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub struct PropertyDeserializer<'a> {
|
pub struct PropertyDeserializer<'a> {
|
||||||
type_name: Option<&'a str>,
|
type_name: Option<&'a str>,
|
||||||
registry: &'a PropertyTypeRegistry,
|
registry: &'a PropertyTypeRegistry,
|
||||||
@ -173,7 +218,7 @@ impl<'a, 'de> DeserializeSeed<'de> for PropertyDeserializer<'a> {
|
|||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
if let Some(type_name) = self.type_name {
|
if let Some(type_name) = self.type_name {
|
||||||
let registration = self.registry.get_short(type_name).ok_or_else(|| {
|
let registration = self.registry.get(type_name).ok_or_else(|| {
|
||||||
de::Error::custom(format!("TypeRegistration is missing for {}", type_name))
|
de::Error::custom(format!("TypeRegistration is missing for {}", type_name))
|
||||||
})?;
|
})?;
|
||||||
let mut erased = erased_serde::Deserializer::erase(deserializer);
|
let mut erased = erased_serde::Deserializer::erase(deserializer);
|
||||||
@ -233,9 +278,7 @@ pub struct MapPropertyDeserializer<'a> {
|
|||||||
|
|
||||||
impl<'a> MapPropertyDeserializer<'a> {
|
impl<'a> MapPropertyDeserializer<'a> {
|
||||||
pub fn new(registry: &'a PropertyTypeRegistry) -> Self {
|
pub fn new(registry: &'a PropertyTypeRegistry) -> Self {
|
||||||
MapPropertyDeserializer {
|
MapPropertyDeserializer { registry }
|
||||||
registry,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +422,26 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> {
|
|||||||
Ok(Box::new(v.to_string()))
|
Ok(Box::new(v.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
|
fn visit_map<V>(self, map: V) -> Result<Self::Value, V::Error>
|
||||||
|
where
|
||||||
|
V: MapAccess<'de>,
|
||||||
|
{
|
||||||
|
Ok(match visit_map(map, self.registry)? {
|
||||||
|
DynamicPropertiesOrProperty::DynamicProperties(value) => Box::new(value),
|
||||||
|
DynamicPropertiesOrProperty::Property(value) => value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DynamicPropertiesOrProperty {
|
||||||
|
DynamicProperties(DynamicProperties),
|
||||||
|
Property(Box<dyn Property>),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<'de, V>(
|
||||||
|
mut map: V,
|
||||||
|
registry: &PropertyTypeRegistry,
|
||||||
|
) -> Result<DynamicPropertiesOrProperty, V::Error>
|
||||||
where
|
where
|
||||||
V: MapAccess<'de>,
|
V: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
@ -394,9 +456,9 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> {
|
|||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
||||||
let mut dynamic_properties =
|
let mut dynamic_properties =
|
||||||
map.next_value_seed(MapPropertyDeserializer { registry: self.registry })?;
|
map.next_value_seed(MapPropertyDeserializer { registry })?;
|
||||||
dynamic_properties.type_name = type_name.to_string();
|
dynamic_properties.type_name = type_name.to_string();
|
||||||
return Ok(Box::new(
|
return Ok(DynamicPropertiesOrProperty::DynamicProperties(
|
||||||
dynamic_properties,
|
dynamic_properties,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -405,9 +467,9 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> {
|
|||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
||||||
let mut dynamic_properties =
|
let mut dynamic_properties =
|
||||||
map.next_value_seed(SeqPropertyDeserializer { registry: self.registry })?;
|
map.next_value_seed(SeqPropertyDeserializer { registry })?;
|
||||||
dynamic_properties.type_name = type_name;
|
dynamic_properties.type_name = type_name;
|
||||||
return Ok(Box::new(
|
return Ok(DynamicPropertiesOrProperty::DynamicProperties(
|
||||||
dynamic_properties,
|
dynamic_properties,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -415,12 +477,12 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> {
|
|||||||
let type_name = type_name
|
let type_name = type_name
|
||||||
.take()
|
.take()
|
||||||
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
.ok_or_else(|| de::Error::missing_field(TYPE_FIELD))?;
|
||||||
return map.next_value_seed(
|
return Ok(DynamicPropertiesOrProperty::Property(map.next_value_seed(
|
||||||
PropertyDeserializer {
|
PropertyDeserializer {
|
||||||
registry: self.registry,
|
registry,
|
||||||
type_name: Some(&type_name),
|
type_name: Some(&type_name),
|
||||||
},
|
},
|
||||||
);
|
)?));
|
||||||
}
|
}
|
||||||
_ => return Err(de::Error::unknown_field(key.as_str(), &[])),
|
_ => return Err(de::Error::unknown_field(key.as_str(), &[])),
|
||||||
}
|
}
|
||||||
@ -428,4 +490,3 @@ impl<'a, 'de> Visitor<'de> for AnyPropVisiter<'a> {
|
|||||||
|
|
||||||
Err(de::Error::custom("Maps in this location must have the \'type\' field and one of the following fields: \'map\', \'seq\', \'value\'"))
|
Err(de::Error::custom("Maps in this location must have the \'type\' field and one of the following fields: \'map\', \'seq\', \'value\'"))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@ -1,4 +1,6 @@
|
|||||||
use crate::{property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry};
|
use crate::{
|
||||||
|
property_serde::DynamicPropertiesDeserializer, DynamicProperties, PropertyTypeRegistry,
|
||||||
|
};
|
||||||
use ron::de::Deserializer;
|
use ron::de::Deserializer;
|
||||||
use serde::de::DeserializeSeed;
|
use serde::de::DeserializeSeed;
|
||||||
|
|
||||||
@ -7,6 +9,7 @@ pub fn deserialize_dynamic_properties(
|
|||||||
property_type_registry: &PropertyTypeRegistry,
|
property_type_registry: &PropertyTypeRegistry,
|
||||||
) -> Result<DynamicProperties, ron::Error> {
|
) -> Result<DynamicProperties, ron::Error> {
|
||||||
let mut deserializer = Deserializer::from_str(&ron_string).unwrap();
|
let mut deserializer = Deserializer::from_str(&ron_string).unwrap();
|
||||||
let dynamic_properties_deserializer = MapPropertyDeserializer::new(&property_type_registry);
|
let dynamic_properties_deserializer =
|
||||||
|
DynamicPropertiesDeserializer::new(&property_type_registry);
|
||||||
dynamic_properties_deserializer.deserialize(&mut deserializer)
|
dynamic_properties_deserializer.deserialize(&mut deserializer)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{Entity, Scene};
|
use crate::{Entity, Scene};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bevy_property::{
|
use bevy_property::{
|
||||||
property_serde::MapPropertyDeserializer, DynamicProperties, PropertyTypeRegistry,
|
property_serde::DynamicPropertiesDeserializer, DynamicProperties, PropertyTypeRegistry,
|
||||||
};
|
};
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor},
|
de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor},
|
||||||
@ -173,7 +173,7 @@ impl<'a, 'de> Visitor<'de> for ComponentSeqVisiter<'a> {
|
|||||||
{
|
{
|
||||||
let mut dynamic_properties = Vec::new();
|
let mut dynamic_properties = Vec::new();
|
||||||
while let Some(entity) =
|
while let Some(entity) =
|
||||||
seq.next_element_seed(MapPropertyDeserializer::new(self.registry))?
|
seq.next_element_seed(DynamicPropertiesDeserializer::new(self.registry))?
|
||||||
{
|
{
|
||||||
dynamic_properties.push(entity);
|
dynamic_properties.push(entity);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user