use serde::{
Deserializer,
de::{DeserializeSeed, MapAccess, SeqAccess, Visitor},
forward_to_deserialize_any,
};
use super::BundleValue;
impl<'de> Deserializer<'de> for BundleValue {
type Error = serde::de::value::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self {
BundleValue::Integer(i) => visitor.visit_i64(i),
BundleValue::Float(f) => visitor.visit_f64(f),
BundleValue::Text(s) => visitor.visit_string(s),
BundleValue::Array(arr) => visitor.visit_seq(SeqDeserializer {
iter: arr.into_iter(),
}),
BundleValue::Map(map) => visitor.visit_map(MapDeserializer {
iter: map.into_iter(),
value: None,
}),
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct
seq tuple tuple_struct map struct enum identifier ignored_any
}
}
struct SeqDeserializer {
iter: std::vec::IntoIter<BundleValue>,
}
impl<'de> SeqAccess<'de> for SeqDeserializer {
type Error = serde::de::value::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.iter.next() {
Some(value) => seed.deserialize(value).map(Some),
None => Ok(None),
}
}
}
struct MapDeserializer {
iter: bevy::platform::collections::hash_map::IntoIter<String, BundleValue>,
value: Option<BundleValue>,
}
impl<'de> MapAccess<'de> for MapDeserializer {
type Error = serde::de::value::Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: DeserializeSeed<'de>,
{
match self.iter.next() {
Some((k, v)) => {
self.value = Some(v);
seed.deserialize(BundleValue::Text(k)).map(Some)
}
None => Ok(None),
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: DeserializeSeed<'de>,
{
let v = self.value.take().unwrap();
seed.deserialize(v)
}
}