summaryrefslogtreecommitdiff
path: root/serde_v8/src
diff options
context:
space:
mode:
Diffstat (limited to 'serde_v8/src')
-rw-r--r--serde_v8/src/de.rs66
1 files changed, 20 insertions, 46 deletions
diff --git a/serde_v8/src/de.rs b/serde_v8/src/de.rs
index 44f94b2d6..24023b05d 100644
--- a/serde_v8/src/de.rs
+++ b/serde_v8/src/de.rs
@@ -375,7 +375,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
// Regular struct
let obj = v8::Local::<v8::Object>::try_from(self.input)
.map_err(|_| Error::ExpectedObject)?;
- let map = ObjectAccess {
+ let struct_access = StructAccess {
fields,
obj,
pos: 0,
@@ -383,7 +383,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
_cache: None,
};
- visitor.visit_map(map)
+ visitor.visit_seq(struct_access)
}
/// To be compatible with `serde-json`, we expect enums to be:
@@ -511,7 +511,7 @@ impl<'de> de::MapAccess<'de> for MapAccess<'_, '_, '_> {
}
}
-struct ObjectAccess<'a, 'b, 's> {
+struct StructAccess<'a, 'b, 's> {
obj: v8::Local<'a, v8::Object>,
scope: &'b mut v8::HandleScope<'s>,
fields: &'static [&'static str],
@@ -519,57 +519,31 @@ struct ObjectAccess<'a, 'b, 's> {
_cache: Option<&'b mut KeyCache>,
}
-fn str_deserializer(s: &str) -> de::value::StrDeserializer<Error> {
- de::IntoDeserializer::into_deserializer(s)
-}
-
-impl<'de, 'a, 'b, 's> de::MapAccess<'de> for ObjectAccess<'a, 'b, 's> {
+impl<'de> de::SeqAccess<'de> for StructAccess<'_, '_, '_> {
type Error = Error;
- fn next_key_seed<K: de::DeserializeSeed<'de>>(
- &mut self,
- seed: K,
- ) -> Result<Option<K::Value>> {
- Ok(match self.fields.get(self.pos) {
- Some(&field) => Some(seed.deserialize(str_deserializer(field))?),
- None => None,
- })
- }
-
- fn next_value_seed<V: de::DeserializeSeed<'de>>(
+ fn next_element_seed<T: de::DeserializeSeed<'de>>(
&mut self,
- seed: V,
- ) -> Result<V::Value> {
+ seed: T,
+ ) -> Result<Option<T::Value>> {
if self.pos >= self.fields.len() {
- return Err(Error::LengthMismatch);
+ return Ok(None);
}
- let field = self.fields[self.pos];
+
+ let pos = self.pos;
self.pos += 1;
- let key = v8_struct_key(self.scope, field).into();
- let v8_val = self.obj.get(self.scope, key).unwrap();
- let mut deserializer = Deserializer::new(self.scope, v8_val, None);
- seed.deserialize(&mut deserializer)
- }
- fn next_entry_seed<
- K: de::DeserializeSeed<'de>,
- V: de::DeserializeSeed<'de>,
- >(
- &mut self,
- kseed: K,
- vseed: V,
- ) -> Result<Option<(K::Value, V::Value)>> {
- if self.pos >= self.fields.len() {
- return Ok(None);
+ let field = self.fields[pos];
+ let key = v8_struct_key(self.scope, field).into();
+ let val = self.obj.get(self.scope, key).unwrap();
+ let mut deserializer = Deserializer::new(self.scope, val, None);
+ match seed.deserialize(&mut deserializer) {
+ Ok(val) => Ok(Some(val)),
+ // Fallback to Ok(None) for #[serde(Default)] at cost of error quality ...
+ // TODO(@AaronO): double check that there's no better solution
+ Err(_) if val.is_undefined() => Ok(None),
+ Err(e) => Err(e),
}
- let field = self.fields[self.pos];
- self.pos += 1;
- Ok(Some((kseed.deserialize(str_deserializer(field))?, {
- let key = v8_struct_key(self.scope, field).into();
- let v8_val = self.obj.get(self.scope, key).unwrap();
- let mut deserializer = Deserializer::new(self.scope, v8_val, None);
- vseed.deserialize(&mut deserializer)?
- })))
}
}