From 7b398a5fc4d1681f95842c65807b7a6bf9fc97e3 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Thu, 14 May 2020 21:51:12 -0600 Subject: [PATCH 01/15] Initial (blank) implementation of serde --- Cargo.toml | 1 + src/value/mod.rs | 2 + src/value/serde.rs | 933 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 936 insertions(+) create mode 100644 src/value/serde.rs diff --git a/Cargo.toml b/Cargo.toml index ac72918..fed939d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ num-bigint = { version = "0.2.2", optional = true } num-traits = { version = "0.2.0", optional = true } log = { version = "0.4.8", optional = true } once_cell = "1.2.0" +serde = { version="1.0.110" } [workspace] members = [ diff --git a/src/value/mod.rs b/src/value/mod.rs index 221120a..f7aaa82 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -281,6 +281,8 @@ impl fmt::Display for ValueError { impl error::Error for ValueError {} +mod serde; + #[cfg(test)] mod tests { #[allow(unused_imports)] diff --git a/src/value/serde.rs b/src/value/serde.rs new file mode 100644 index 0000000..81dc31e --- /dev/null +++ b/src/value/serde.rs @@ -0,0 +1,933 @@ +// imports {{{ +use std; +use std::fmt::{self, Display}; +use std::ops::{AddAssign, MulAssign, Neg}; + +use serde::de::{ + self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, + Visitor, +}; +use serde::Deserialize; +use serde::{ser, Serialize}; + +use super::JsValue; +// }}} + +// error {{{ +pub type Result = std::result::Result; + +#[derive(Clone, Debug, PartialEq)] +pub enum Error { + Message(String), + Eof, + Syntax, + ExpectedBoolean, + ExpectedInteger, + ExpectedString, + ExpectedNull, + ExpectedArray, + ExpectedArrayComma, + ExpectedArrayEnd, + ExpectedMap, + ExpectedMapColon, + ExpectedMapComma, + ExpectedMapEnd, + ExpectedEnum, + TrailingCharacters, +} + +impl ser::Error for Error { + fn custom(msg: T) -> Self { + Error::Message(msg.to_string()) + } +} + +impl de::Error for Error { + fn custom(msg: T) -> Self { + Error::Message(msg.to_string()) + } +} + +impl Display for Error { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + _ => unimplemented!(), + } + } +} + +impl std::error::Error for Error {} +// }}} + +// ser {{{ +pub struct Serializer; + +pub fn to_js_value(value: &T) -> Result +where + T: Serialize, +{ + let mut serializer = Serializer; + value.serialize(&mut serializer) +} + +// impl ser::Serializer {{{ +impl<'a> ser::Serializer for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + type SerializeSeq = Self; + type SerializeTuple = Self; + type SerializeTupleStruct = Self; + type SerializeTupleVariant = Self; + type SerializeMap = Self; + type SerializeStruct = Self; + type SerializeStructVariant = Self; + + fn serialize_bool(self, v: bool) -> Result { + Ok(JsValue::Bool(v)) + } + + // JSON does not distinguish between different sizes of integers, so all + // signed integers will be serialized the same and all unsigned integers + // will be serialized the same. Other formats, especially compact binary + // formats, may need independent logic for the different sizes. + fn serialize_i8(self, v: i8) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_i16(self, v: i16) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_i32(self, v: i32) -> Result { + Ok(JsValue::Int(v)) + } + + // Not particularly efficient but this is example code anyway. A more + // performant approach would be to use the `itoa` crate. + fn serialize_i64(self, v: i64) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_u8(self, v: u8) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_u16(self, v: u16) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_u32(self, v: u32) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_u64(self, v: u64) -> Result { + Ok(JsValue::Int(v as i32)) + } + + fn serialize_f32(self, v: f32) -> Result { + Ok(JsValue::Float(v.into())) + } + + fn serialize_f64(self, v: f64) -> Result { + Ok(JsValue::Float(f64::from(v))) + } + + fn serialize_char(self, v: char) -> Result { + Ok(JsValue::String(format!("{}", v))) + } + + fn serialize_str(self, v: &str) -> Result { + Ok(JsValue::String(v.into())) + } + + fn serialize_bytes(self, v: &[u8]) -> Result { + todo!() + } + + fn serialize_none(self) -> Result { + Ok(JsValue::Null) + } + + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_unit(self) -> Result { + self.serialize_none() + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + todo!() + } + + // Now we get to the serialization of compound types. + // + // The start of the sequence, each value, and the end are three separate + // method calls. This one is responsible only for serializing the start, + // which in JSON is `[`. + // + // The length of the sequence may or may not be known ahead of time. This + // doesn't make a difference in JSON because the length is not represented + // explicitly in the serialized form. Some serializers may only be able to + // support sequences for which the length is known up front. + fn serialize_seq(self, _len: Option) -> Result { + // self.output += "["; + // Ok(self) + todo!() + } + + // Tuples look just like sequences in JSON. Some formats may be able to + // represent tuples more efficiently by omitting the length, since tuple + // means that the corresponding `Deserialize implementation will know the + // length without needing to look at the serialized data. + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + // Tuple structs look just like sequences in JSON. + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + // Tuple variants are represented in JSON as `{ NAME: [DATA...] }`. Again + // this method is only responsible for the externally tagged representation. + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + // self.output += "{"; + // variant.serialize(&mut *self)?; + // self.output += ":["; + // Ok(self) + todo!() + } + + // Maps are represented in JSON as `{ K: V, K: V, ... }`. + fn serialize_map(self, _len: Option) -> Result { + // self.output += "{"; + // Ok(self) + todo!() + } + + // Structs look just like maps in JSON. In particular, JSON requires that we + // serialize the field names of the struct. Other formats may be able to + // omit the field names when serializing structs because the corresponding + // Deserialize implementation is required to know what the keys are without + // looking at the serialized data. + fn serialize_struct(self, _name: &'static str, len: usize) -> Result { + self.serialize_map(Some(len)) + } + + // Struct variants are represented in JSON as `{ NAME: { K: V, ... } }`. + // This is the externally tagged representation. + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + // self.output += "{"; + // variant.serialize(&mut *self)?; + // self.output += ":{"; + // Ok(self) + todo!(); + } +} +// }}} + +// impl ser::SerializeSeq {{{ +impl<'a> ser::SerializeSeq for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + // Serialize a single element of the sequence. + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('[') { + // self.output += ","; + // } + // value.serialize(&mut **self) + todo!() + } + + // Close the sequence. + fn end(self) -> Result { + // self.output += "]"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeTuple {{{ +impl<'a> ser::SerializeTuple for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('[') { + // self.output += ","; + // } + // value.serialize(&mut **self) + todo!() + } + + fn end(self) -> Result { + // self.output += "]"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeTupleStruct {{{ +impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('[') { + // self.output += ","; + // } + // value.serialize(&mut **self) + todo!() + } + + fn end(self) -> Result { + // self.output += "]"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeTupleVariant {{{ +// Tuple variants are a little different. Refer back to the +// `serialize_tuple_variant` method above: +// +// self.output += "{"; +// variant.serialize(&mut *self)?; +// self.output += ":["; +// +// So the `end` method in this impl is responsible for closing both the `]` and +// the `}`. +impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('[') { + // self.output += ","; + // } + // value.serialize(&mut **self) + todo!() + } + + fn end(self) -> Result { + // self.output += "]}"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeMap {{{ +// Some `Serialize` types are not able to hold a key and value in memory at the +// same time so `SerializeMap` implementations are required to support +// `serialize_key` and `serialize_value` individually. +// +// There is a third optional method on the `SerializeMap` trait. The +// `serialize_entry` method allows serializers to optimize for the case where +// key and value are both available simultaneously. In JSON it doesn't make a +// difference so the default behavior for `serialize_entry` is fine. +impl<'a> ser::SerializeMap for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + // The Serde data model allows map keys to be any serializable type. JSON + // only allows string keys so the implementation below will produce invalid + // JSON if the key serializes as something other than a string. + // + // A real JSON serializer would need to validate that map keys are strings. + // This can be done by using a different Serializer to serialize the key + // (instead of `&mut **self`) and having that other serializer only + // implement `serialize_str` and return an error on any other data type. + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('{') { + // self.output += ","; + // } + // key.serialize(&mut **self) + todo!() + } + + // It doesn't make a difference whether the colon is printed at the end of + // `serialize_key` or at the beginning of `serialize_value`. In this case + // the code is a bit simpler having it here. + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + value.serialize(&mut **self); + todo!(); + Ok(()) + } + + fn end(self) -> Result { + // self.output += "}"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeStruct {{{ +// Structs are like maps in which the keys are constrained to be compile-time +// constant strings. +impl<'a> ser::SerializeStruct for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('{') { + // self.output += ","; + // } + // key.serialize(&mut **self)?; + // self.output += ":"; + // value.serialize(&mut **self) + todo!() + } + + fn end(self) -> Result { + // self.output += "}"; + // Ok(()) + todo!() + } +} +// }}} + +// ser::SerializeStructVariant {{{ +// Similar to `SerializeTupleVariant`, here the `end` method is responsible for +// closing both of the curly braces opened by `serialize_struct_variant`. +impl<'a> ser::SerializeStructVariant for &'a mut Serializer { + type Ok = JsValue; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + // if !self.output.ends_with('{') { + // self.output += ","; + // } + // key.serialize(&mut **self)?; + // self.output += ":"; + // value.serialize(&mut **self) + todo!() + } + + fn end(self) -> Result { + todo!() + } +} +// }}} + +// ser tests {{{ +#[test] +fn test_struct() { + #[derive(Serialize)] + struct Test { + int: u32, + seq: Vec<&'static str>, + } + + let test = Test { + int: 1, + seq: vec!["a", "b"], + }; + let expected = r#"{"int":1,"seq":["a","b"]}"#; + assert_eq!(to_js_value(&test).unwrap(), expected); +} + +#[test] +fn test_enum() { + #[derive(Serialize)] + enum E { + Unit, + Newtype(u32), + Tuple(u32, u32), + Struct { a: u32 }, + } + + let u = E::Unit; + let expected = r#""Unit""#; + assert_eq!(to_js_value(&u).unwrap(), expected); + + let n = E::Newtype(1); + let expected = r#"{"Newtype":1}"#; + assert_eq!(to_js_value(&n).unwrap(), expected); + + let t = E::Tuple(1, 2); + let expected = r#"{"Tuple":[1,2]}"#; + assert_eq!(to_js_value(&t).unwrap(), expected); + + let s = E::Struct { a: 1 }; + let expected = r#"{"Struct":{"a":1}}"#; + assert_eq!(to_js_value(&s).unwrap(), expected); +} +// }}} +// }}} + +// de {{{ +pub struct Deserializer<'de> { + input: &'de JsValue, +} + +impl<'de> Deserializer<'de> { + pub fn from_js_value(input: &'de JsValue) -> Self { + Deserializer { input } + } +} + +pub fn from_js_value<'a, T>(val: &'a JsValue) -> Result +where + T: Deserialize<'a>, +{ + let mut deserializer = Deserializer::from_js_value(val); + T::deserialize(&mut deserializer) +} + +// de::Deserializer {{{ +impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // match self.peek_char()? { + // 'n' => self.deserialize_unit(visitor), + // 't' | 'f' => self.deserialize_bool(visitor), + // '"' => self.deserialize_str(visitor), + // '0'..='9' => self.deserialize_u64(visitor), + // '-' => self.deserialize_i64(visitor), + // '[' => self.deserialize_seq(visitor), + // '{' => self.deserialize_map(visitor), + // _ => Err(Error::Syntax), + // } + todo!() + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_bool(todo!()) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_i8(todo!()) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_i16(todo!()) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_i32(todo!()) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_i64(todo!()) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_u8(todo!()) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_u16(todo!()) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_u32(todo!()) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_u64(todo!()) + } + + fn deserialize_f32(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_f64(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_char(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_borrowed_str(todo!()) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + unimplemented!() + } + + fn deserialize_byte_buf(self, _visitor: V) -> Result + where + V: Visitor<'de>, + { + unimplemented!() + } + + // An absent optional is represented as the JSON `null` and a present + // optional is represented as just the contained value. + // + // As commented in `Serializer` implementation, this is a lossy + // representation. For example the values `Some(())` and `None` both + // serialize as just `null`. Unfortunately this is typically what people + // expect when working with JSON. Other formats are encouraged to behave + // more intelligently if possible. + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // if self.input.starts_with("null") { + // self.input = &self.input["null".len()..]; + // visitor.visit_none() + // } else { + // visitor.visit_some(self) + // } + todo!() + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // if self.input.starts_with("null") { + // self.input = &self.input["null".len()..]; + // visitor.visit_unit() + // } else { + // Err(Error::ExpectedNull) + // } + todo!() + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + // As is done here, serializers are encouraged to treat newtype structs as + // insignificant wrappers around the data they contain. That means not + // parsing anything other than the contained value. + fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + // Deserialization of compound types like sequences and maps happens by + // passing the visitor an "Access" object that gives it the ability to + // iterate through the data contained in the sequence. + fn deserialize_seq(mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // // Parse the opening bracket of the sequence. + // if self.next_char()? == '[' { + // // Give the visitor access to each element of the sequence. + // let value = visitor.visit_seq(CommaSeparated::new(&mut self))?; + // // Parse the closing bracket of the sequence. + // if self.next_char()? == ']' { + // Ok(value) + // } else { + // Err(Error::ExpectedArrayEnd) + // } + // } else { + // Err(Error::ExpectedArray) + // } + todo!() + } + + // Tuples look just like sequences in JSON. Some formats may be able to + // represent tuples more efficiently. + // + // As indicated by the length parameter, the `Deserialize` implementation + // for a tuple in the Serde data model is required to know the length of the + // tuple before even looking at the input data. + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + // Tuple structs look just like sequences in JSON. + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + // Much like `deserialize_seq` but calls the visitors `visit_map` method + // with a `MapAccess` implementation, rather than the visitor's `visit_seq` + // method with a `SeqAccess` implementation. + fn deserialize_map(mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // // Parse the opening brace of the map. + // if self.next_char()? == '{' { + // // Give the visitor access to each entry of the map. + // let value = visitor.visit_map(CommaSeparated::new(&mut self))?; + // // Parse the closing brace of the map. + // if self.next_char()? == '}' { + // Ok(value) + // } else { + // Err(Error::ExpectedMapEnd) + // } + // } else { + // Err(Error::ExpectedMap) + // } + todo!() + } + + // Structs look just like maps in JSON. + // + // Notice the `fields` parameter - a "struct" in the Serde data model means + // that the `Deserialize` implementation is required to know what the fields + // are before even looking at the input data. Any key-value pairing in which + // the fields cannot be known ahead of time is probably a map. + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_map(visitor) + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + // if self.peek_char()? == '"' { + // // Visit a unit variant. + // visitor.visit_enum(self.parse_string()?.into_deserializer()) + // } else if self.next_char()? == '{' { + // // Visit a newtype variant, tuple variant, or struct variant. + // let value = visitor.visit_enum(Enum::new(self))?; + // // Parse the matching close brace. + // if self.next_char()? == '}' { + // Ok(value) + // } else { + // Err(Error::ExpectedMapEnd) + // } + // } else { + // Err(Error::ExpectedEnum) + // } + todo!() + } + + // An identifier in Serde is the type that identifies a field of a struct or + // the variant of an enum. In JSON, struct fields and enum variants are + // represented as strings. In other formats they may be represented as + // numeric indices. + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + // Like `deserialize_any` but indicates to the `Deserializer` that it makes + // no difference which `Visitor` method is called because the data is + // ignored. + // + // Some deserializers are able to implement this more efficiently than + // `deserialize_any`, for example by rapidly skipping over matched + // delimiters without paying close attention to the data in between. + // + // Some formats are not able to implement this at all. Formats that can + // implement `deserialize_any` and `deserialize_ignored_any` are known as + // self-describing. + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } +} +// }}} + +// de tests {{{ +#[test] +fn test_struct() { + #[derive(Deserialize, PartialEq, Debug)] + struct Test { + int: u32, + seq: Vec, + } + + let j = r#"{"int":1,"seq":["a","b"]}"#; + let expected = Test { + int: 1, + seq: vec!["a".to_owned(), "b".to_owned()], + }; + assert_eq!(expected, from_js_value(j).unwrap()); +} + +#[test] +fn test_enum() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Unit, + Newtype(u32), + Tuple(u32, u32), + Struct { a: u32 }, + } + + let j = r#""Unit""#; + let expected = E::Unit; + assert_eq!(expected, from_js_value(j).unwrap()); + + let j = r#"{"Newtype":1}"#; + let expected = E::Newtype(1); + assert_eq!(expected, from_js_value(j).unwrap()); + + let j = r#"{"Tuple":[1,2]}"#; + let expected = E::Tuple(1, 2); + assert_eq!(expected, from_js_value(j).unwrap()); + + let j = r#"{"Struct":{"a":1}}"#; + let expected = E::Struct { a: 1 }; + assert_eq!(expected, from_js_value(j).unwrap()); +} +// }}} +// }}} From c0e7bb46bf0249a3be3e88df57db449f344dba40 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Wed, 20 May 2020 22:57:57 -0600 Subject: [PATCH 02/15] Basic serialization from struct => JsValue is working! --- Cargo.toml | 2 +- src/value/serde.rs | 288 ++++++++++++++++++++++++--------------------- 2 files changed, 155 insertions(+), 135 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fed939d..e67b2af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ num-bigint = { version = "0.2.2", optional = true } num-traits = { version = "0.2.0", optional = true } log = { version = "0.4.8", optional = true } once_cell = "1.2.0" -serde = { version="1.0.110" } +serde = { version="1.0.110", features=["derive"] } [workspace] members = [ diff --git a/src/value/serde.rs b/src/value/serde.rs index 81dc31e..4ab129f 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -60,13 +60,17 @@ impl std::error::Error for Error {} // }}} // ser {{{ -pub struct Serializer; +pub struct Serializer { + pending_js_value: Vec, +} pub fn to_js_value(value: &T) -> Result where T: Serialize, { - let mut serializer = Serializer; + let mut serializer = Serializer { + pending_js_value: vec![], + }; value.serialize(&mut serializer) } @@ -142,7 +146,11 @@ impl<'a> ser::Serializer for &'a mut Serializer { } fn serialize_bytes(self, v: &[u8]) -> Result { - todo!() + let mut vec = Vec::::with_capacity(v.len()); + for i in v { + vec.push(self.serialize_u8(*i)?); + } + Ok(JsValue::Array(vec)) } fn serialize_none(self) -> Result { @@ -180,6 +188,7 @@ impl<'a> ser::Serializer for &'a mut Serializer { value.serialize(self) } + /// Serialize a newtype variant like E::N in enum E { N(u8) } fn serialize_newtype_variant( self, _name: &'static str, @@ -193,20 +202,9 @@ impl<'a> ser::Serializer for &'a mut Serializer { todo!() } - // Now we get to the serialization of compound types. - // - // The start of the sequence, each value, and the end are three separate - // method calls. This one is responsible only for serializing the start, - // which in JSON is `[`. - // - // The length of the sequence may or may not be known ahead of time. This - // doesn't make a difference in JSON because the length is not represented - // explicitly in the serialized form. Some serializers may only be able to - // support sequences for which the length is known up front. fn serialize_seq(self, _len: Option) -> Result { - // self.output += "["; - // Ok(self) - todo!() + self.pending_js_value.push(JsValue::Array(vec![])); + Ok(self) } // Tuples look just like sequences in JSON. Some formats may be able to @@ -242,18 +240,12 @@ impl<'a> ser::Serializer for &'a mut Serializer { todo!() } - // Maps are represented in JSON as `{ K: V, K: V, ... }`. fn serialize_map(self, _len: Option) -> Result { - // self.output += "{"; - // Ok(self) - todo!() + use std::collections::HashMap; + self.pending_js_value.push(JsValue::Object(HashMap::new())); + Ok(self) } - // Structs look just like maps in JSON. In particular, JSON requires that we - // serialize the field names of the struct. Other formats may be able to - // omit the field names when serializing structs because the corresponding - // Deserialize implementation is required to know what the keys are without - // looking at the serialized data. fn serialize_struct(self, _name: &'static str, len: usize) -> Result { self.serialize_map(Some(len)) } @@ -286,18 +278,20 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('[') { - // self.output += ","; - // } - // value.serialize(&mut **self) - todo!() + let value = value.serialize(&mut **self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Array(arr)) => { + arr.push(value); + Ok(()) + } + _ => return Err(Error::Message("Inner pending value is not an array".into())), + } } - // Close the sequence. fn end(self) -> Result { - // self.output += "]"; - // Ok(()) - todo!() + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending value is None".into())) } } // }}} @@ -396,41 +390,50 @@ impl<'a> ser::SerializeMap for &'a mut Serializer { type Ok = JsValue; type Error = Error; - // The Serde data model allows map keys to be any serializable type. JSON - // only allows string keys so the implementation below will produce invalid - // JSON if the key serializes as something other than a string. - // - // A real JSON serializer would need to validate that map keys are strings. - // This can be done by using a different Serializer to serialize the key - // (instead of `&mut **self`) and having that other serializer only - // implement `serialize_str` and return an error on any other data type. + // empty methods (unneeded) {{{ fn serialize_key(&mut self, key: &T) -> Result<()> where T: ?Sized + Serialize, { - // if !self.output.ends_with('{') { - // self.output += ","; - // } - // key.serialize(&mut **self) - todo!() + Ok(()) } - // It doesn't make a difference whether the colon is printed at the end of - // `serialize_key` or at the beginning of `serialize_value`. In this case - // the code is a bit simpler having it here. fn serialize_value(&mut self, value: &T) -> Result<()> where T: ?Sized + Serialize, { - value.serialize(&mut **self); - todo!(); Ok(()) } + // }}} + + fn serialize_entry(&mut self, key: &K, value: &V) -> Result<()> + where + K: Serialize, + V: Serialize, + { + let key = key.serialize(&mut **self)?; + let key_as_string = match key { + JsValue::String(s) => s, + _ => return Err(Error::Message("Expected key to be a string".into())), + }; + let value = value.serialize(&mut **self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Object(map)) => { + map.insert(key_as_string, value); + Ok(()) + } + _ => { + return Err(Error::Message( + "Inner pending object is not a JsValue::Object".into(), + )) + } + } + } fn end(self) -> Result { - // self.output += "}"; - // Ok(()) - todo!() + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending object is None".into())) } } // }}} @@ -446,19 +449,24 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('{') { - // self.output += ","; - // } - // key.serialize(&mut **self)?; - // self.output += ":"; - // value.serialize(&mut **self) - todo!() + let value = value.serialize(&mut **self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Object(map)) => { + map.insert(key.into(), value); + Ok(()) + } + _ => { + return Err(Error::Message( + "Inner pending object is not a JsValue::Object".into(), + )) + } + } } fn end(self) -> Result { - // self.output += "}"; - // Ok(()) - todo!() + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending object is None".into())) } } // }}} @@ -492,6 +500,9 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { // ser tests {{{ #[test] fn test_struct() { + use serde::Serialize; + use std::collections::HashMap; + #[derive(Serialize)] struct Test { int: u32, @@ -502,36 +513,45 @@ fn test_struct() { int: 1, seq: vec!["a", "b"], }; - let expected = r#"{"int":1,"seq":["a","b"]}"#; + let mut map = HashMap::new(); + map.insert("int".into(), JsValue::Int(1)); + map.insert( + "seq".into(), + JsValue::Array(vec![ + JsValue::String("a".into()), + JsValue::String("b".into()), + ]), + ); + let expected = JsValue::Object(map); assert_eq!(to_js_value(&test).unwrap(), expected); } -#[test] -fn test_enum() { - #[derive(Serialize)] - enum E { - Unit, - Newtype(u32), - Tuple(u32, u32), - Struct { a: u32 }, - } - - let u = E::Unit; - let expected = r#""Unit""#; - assert_eq!(to_js_value(&u).unwrap(), expected); - - let n = E::Newtype(1); - let expected = r#"{"Newtype":1}"#; - assert_eq!(to_js_value(&n).unwrap(), expected); - - let t = E::Tuple(1, 2); - let expected = r#"{"Tuple":[1,2]}"#; - assert_eq!(to_js_value(&t).unwrap(), expected); - - let s = E::Struct { a: 1 }; - let expected = r#"{"Struct":{"a":1}}"#; - assert_eq!(to_js_value(&s).unwrap(), expected); -} +// #[test] +// fn test_enum() { +// #[derive(Serialize)] +// enum E { +// Unit, +// Newtype(u32), +// Tuple(u32, u32), +// Struct { a: u32 }, +// } +// +// let u = E::Unit; +// let expected = r#""Unit""#; +// assert_eq!(to_js_value(&u).unwrap(), expected); +// +// let n = E::Newtype(1); +// let expected = r#"{"Newtype":1}"#; +// assert_eq!(to_js_value(&n).unwrap(), expected); +// +// let t = E::Tuple(1, 2); +// let expected = r#"{"Tuple":[1,2]}"#; +// assert_eq!(to_js_value(&t).unwrap(), expected); +// +// let s = E::Struct { a: 1 }; +// let expected = r#"{"Struct":{"a":1}}"#; +// assert_eq!(to_js_value(&s).unwrap(), expected); +// } // }}} // }}} @@ -887,47 +907,47 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { // }}} // de tests {{{ -#[test] -fn test_struct() { - #[derive(Deserialize, PartialEq, Debug)] - struct Test { - int: u32, - seq: Vec, - } - - let j = r#"{"int":1,"seq":["a","b"]}"#; - let expected = Test { - int: 1, - seq: vec!["a".to_owned(), "b".to_owned()], - }; - assert_eq!(expected, from_js_value(j).unwrap()); -} - -#[test] -fn test_enum() { - #[derive(Deserialize, PartialEq, Debug)] - enum E { - Unit, - Newtype(u32), - Tuple(u32, u32), - Struct { a: u32 }, - } - - let j = r#""Unit""#; - let expected = E::Unit; - assert_eq!(expected, from_js_value(j).unwrap()); - - let j = r#"{"Newtype":1}"#; - let expected = E::Newtype(1); - assert_eq!(expected, from_js_value(j).unwrap()); - - let j = r#"{"Tuple":[1,2]}"#; - let expected = E::Tuple(1, 2); - assert_eq!(expected, from_js_value(j).unwrap()); - - let j = r#"{"Struct":{"a":1}}"#; - let expected = E::Struct { a: 1 }; - assert_eq!(expected, from_js_value(j).unwrap()); -} +// #[test] +// fn test_struct() { +// #[derive(Deserialize, PartialEq, Debug)] +// struct Test { +// int: u32, +// seq: Vec, +// } +// +// let j = r#"{"int":1,"seq":["a","b"]}"#; +// let expected = Test { +// int: 1, +// seq: vec!["a".to_owned(), "b".to_owned()], +// }; +// assert_eq!(expected, from_js_value(j).unwrap()); +// } +// +// #[test] +// fn test_enum() { +// #[derive(Deserialize, PartialEq, Debug)] +// enum E { +// Unit, +// Newtype(u32), +// Tuple(u32, u32), +// Struct { a: u32 }, +// } +// +// let j = r#""Unit""#; +// let expected = E::Unit; +// assert_eq!(expected, from_js_value(j).unwrap()); +// +// let j = r#"{"Newtype":1}"#; +// let expected = E::Newtype(1); +// assert_eq!(expected, from_js_value(j).unwrap()); +// +// let j = r#"{"Tuple":[1,2]}"#; +// let expected = E::Tuple(1, 2); +// assert_eq!(expected, from_js_value(j).unwrap()); +// +// let j = r#"{"Struct":{"a":1}}"#; +// let expected = E::Struct { a: 1 }; +// assert_eq!(expected, from_js_value(j).unwrap()); +// } // }}} // }}} From 0b91cc74ff34ecee876725d6b371b1c1ac11cd01 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Thu, 28 May 2020 20:58:55 -0600 Subject: [PATCH 03/15] More serialization tests pass; in need of code de-duplication. --- src/value/serde.rs | 167 +++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 60 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 4ab129f..3cb3eaf 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -1,5 +1,6 @@ // imports {{{ use std; +use std::collections::HashMap; use std::fmt::{self, Display}; use std::ops::{AddAssign, MulAssign, Neg}; @@ -61,6 +62,7 @@ impl std::error::Error for Error {} // ser {{{ pub struct Serializer { + pending_hashmap_key: Option, pending_js_value: Vec, } @@ -69,6 +71,7 @@ where T: Serialize, { let mut serializer = Serializer { + pending_hashmap_key: None, pending_js_value: vec![], }; value.serialize(&mut serializer) @@ -199,7 +202,9 @@ impl<'a> ser::Serializer for &'a mut Serializer { where T: ?Sized + Serialize, { - todo!() + let mut map = HashMap::new(); + map.insert(variant.into(), value.serialize(self)?); + Ok(JsValue::Object(map)) } fn serialize_seq(self, _len: Option) -> Result { @@ -233,15 +238,12 @@ impl<'a> ser::Serializer for &'a mut Serializer { variant: &'static str, _len: usize, ) -> Result { - // self.output += "{"; - // variant.serialize(&mut *self)?; - // self.output += ":["; - // Ok(self) - todo!() + self.pending_hashmap_key = Some(variant.into()); + self.pending_js_value.push(JsValue::Array(vec![])); + Ok(self) } fn serialize_map(self, _len: Option) -> Result { - use std::collections::HashMap; self.pending_js_value.push(JsValue::Object(HashMap::new())); Ok(self) } @@ -259,11 +261,9 @@ impl<'a> ser::Serializer for &'a mut Serializer { variant: &'static str, _len: usize, ) -> Result { - // self.output += "{"; - // variant.serialize(&mut *self)?; - // self.output += ":{"; - // Ok(self) - todo!(); + self.pending_hashmap_key = Some(variant.into()); + self.pending_js_value.push(JsValue::Object(HashMap::new())); + Ok(self) } } // }}} @@ -305,17 +305,20 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('[') { - // self.output += ","; - // } - // value.serialize(&mut **self) - todo!() + let value = value.serialize(&mut **self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Array(arr)) => { + arr.push(value); + Ok(()) + } + _ => return Err(Error::Message("Inner pending value is not an array".into())), + } } fn end(self) -> Result { - // self.output += "]"; - // Ok(()) - todo!() + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending value is None".into())) } } // }}} @@ -365,14 +368,29 @@ impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { // if !self.output.ends_with('[') { // self.output += ","; // } - // value.serialize(&mut **self) - todo!() + let value = value.serialize(&mut **self)?; + match self.pending_js_value.last_mut() { + Some(JsValue::Array(arr)) => { + arr.push(value); + Ok(()) + } + _ => return Err(Error::Message("Inner pending value is not an array".into())), + } } fn end(self) -> Result { - // self.output += "]}"; - // Ok(()) - todo!() + let value = self + .pending_js_value + .pop() + .ok_or(Error::Message("Inner pending value is None".into()))?; + let mut map = HashMap::new(); + map.insert( + self.pending_hashmap_key + .take() + .ok_or(Error::Message("Inner pending HashMap key is None".into()))?, + value, + ); + Ok(JsValue::Object(map)) } } // }}} @@ -482,17 +500,32 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('{') { - // self.output += ","; - // } - // key.serialize(&mut **self)?; - // self.output += ":"; - // value.serialize(&mut **self) - todo!() + let value = value.serialize(&mut **self)?; + match self.pending_js_value.last_mut() { + Some(JsValue::Object(map)) => { + map.insert(key.into(), value); + Ok(()) + } + _ => { + return Err(Error::Message( + "Inner pending value is not an object".into(), + )) + } + } } fn end(self) -> Result { - todo!() + let key = self + .pending_hashmap_key + .take() + .ok_or(Error::Message("The pending HashMap key is None".into()))?; + let value = self + .pending_js_value + .pop() + .ok_or(Error::Message("Inner pending value is None".into()))?; + let mut map = HashMap::new(); + map.insert(key, value); + Ok(JsValue::Object(map)) } } // }}} @@ -501,7 +534,6 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { #[test] fn test_struct() { use serde::Serialize; - use std::collections::HashMap; #[derive(Serialize)] struct Test { @@ -524,34 +556,49 @@ fn test_struct() { ); let expected = JsValue::Object(map); assert_eq!(to_js_value(&test).unwrap(), expected); + + let tuple = (1, 2); + let expected = JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]); + assert_eq!(to_js_value(&tuple).unwrap(), expected); } -// #[test] -// fn test_enum() { -// #[derive(Serialize)] -// enum E { -// Unit, -// Newtype(u32), -// Tuple(u32, u32), -// Struct { a: u32 }, -// } -// -// let u = E::Unit; -// let expected = r#""Unit""#; -// assert_eq!(to_js_value(&u).unwrap(), expected); -// -// let n = E::Newtype(1); -// let expected = r#"{"Newtype":1}"#; -// assert_eq!(to_js_value(&n).unwrap(), expected); -// -// let t = E::Tuple(1, 2); -// let expected = r#"{"Tuple":[1,2]}"#; -// assert_eq!(to_js_value(&t).unwrap(), expected); -// -// let s = E::Struct { a: 1 }; -// let expected = r#"{"Struct":{"a":1}}"#; -// assert_eq!(to_js_value(&s).unwrap(), expected); -// } +#[test] +fn test_enum() { + #[derive(Serialize)] + enum E { + Unit, + Newtype(u32), + Tuple(u32, u32), + Struct { a: u32 }, + } + + let u = E::Unit; + let expected = JsValue::String("Unit".into()); + assert_eq!(to_js_value(&u).unwrap(), expected); + + let n = E::Newtype(1); + let mut map = HashMap::new(); + map.insert("Newtype".into(), JsValue::Int(1)); + let expected = JsValue::Object(map); + assert_eq!(to_js_value(&n).unwrap(), expected); + + let t = E::Tuple(1, 2); + let mut map = HashMap::new(); + map.insert( + "Tuple".into(), + JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]), + ); + let expected = JsValue::Object(map); + assert_eq!(to_js_value(&t).unwrap(), expected); + + let s = E::Struct { a: 1 }; + let mut inner_map = HashMap::new(); + inner_map.insert("a".into(), JsValue::Int(1)); + let mut map = HashMap::new(); + map.insert("Struct".into(), JsValue::Object(inner_map)); + let expected = JsValue::Object(map); + assert_eq!(to_js_value(&s).unwrap(), expected); +} // }}} // }}} From db313ba7d63cb39f5c11f866fc234fa7ff0825bd Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Thu, 28 May 2020 22:43:47 -0600 Subject: [PATCH 04/15] Pull out some common serialization utility methods --- src/value/serde.rs | 181 ++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 99 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 3cb3eaf..22afdff 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -66,6 +66,70 @@ pub struct Serializer { pending_js_value: Vec, } +// impl Serializer {{{ +impl Serializer { + fn serialize_keyvalue_to_pending_map( + &mut self, + key: &K, + value: &V, + ) -> Result<()> + where + K: Serialize, + V: Serialize, + { + let key = key.serialize(&mut *self)?; + let key_as_string = match key { + JsValue::String(s) => s, + _ => return Err(Error::Message("Expected key to be a string".into())), + }; + let value = value.serialize(&mut *self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Object(map)) => { + map.insert(key_as_string, value); + Ok(()) + } + _ => { + return Err(Error::Message( + "Inner pending object is not a JsValue::Object".into(), + )) + } + } + } + + fn end_pending_map(&mut self) -> Result { + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending object is None".into())) + } + + fn serialize_element_to_pending_array(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let value = value.serialize(&mut *self)?; + match &mut self.pending_js_value.last_mut() { + Some(JsValue::Array(arr)) => { + arr.push(value); + Ok(()) + } + _ => return Err(Error::Message("Inner pending value is not an array".into())), + } + } + + fn end_pending_array(&mut self) -> Result { + self.pending_js_value + .pop() + .ok_or(Error::Message("Inner pending value is None".into())) + } + + fn wrap_in_map_with_key(&self, key: String, value: JsValue) -> JsValue { + let mut map = HashMap::new(); + map.insert(key, value); + JsValue::Object(map) + } +} +// }}} + pub fn to_js_value(value: &T) -> Result where T: Serialize, @@ -278,20 +342,11 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer { where T: ?Sized + Serialize, { - let value = value.serialize(&mut **self)?; - match &mut self.pending_js_value.last_mut() { - Some(JsValue::Array(arr)) => { - arr.push(value); - Ok(()) - } - _ => return Err(Error::Message("Inner pending value is not an array".into())), - } + self.serialize_element_to_pending_array(value) } fn end(self) -> Result { - self.pending_js_value - .pop() - .ok_or(Error::Message("Inner pending value is None".into())) + self.end_pending_array() } } // }}} @@ -305,20 +360,11 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer { where T: ?Sized + Serialize, { - let value = value.serialize(&mut **self)?; - match &mut self.pending_js_value.last_mut() { - Some(JsValue::Array(arr)) => { - arr.push(value); - Ok(()) - } - _ => return Err(Error::Message("Inner pending value is not an array".into())), - } + self.serialize_element_to_pending_array(value) } fn end(self) -> Result { - self.pending_js_value - .pop() - .ok_or(Error::Message("Inner pending value is None".into())) + self.end_pending_array() } } // }}} @@ -365,32 +411,16 @@ impl<'a> ser::SerializeTupleVariant for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('[') { - // self.output += ","; - // } - let value = value.serialize(&mut **self)?; - match self.pending_js_value.last_mut() { - Some(JsValue::Array(arr)) => { - arr.push(value); - Ok(()) - } - _ => return Err(Error::Message("Inner pending value is not an array".into())), - } + self.serialize_element_to_pending_array(value) } fn end(self) -> Result { - let value = self - .pending_js_value - .pop() - .ok_or(Error::Message("Inner pending value is None".into()))?; - let mut map = HashMap::new(); - map.insert( - self.pending_hashmap_key - .take() - .ok_or(Error::Message("Inner pending HashMap key is None".into()))?, - value, - ); - Ok(JsValue::Object(map)) + let value = self.end_pending_array()?; + let key = self + .pending_hashmap_key + .take() + .ok_or(Error::Message("Inner pending HashMap key is None".into()))?; + Ok(self.wrap_in_map_with_key(key, value)) } } // }}} @@ -429,29 +459,11 @@ impl<'a> ser::SerializeMap for &'a mut Serializer { K: Serialize, V: Serialize, { - let key = key.serialize(&mut **self)?; - let key_as_string = match key { - JsValue::String(s) => s, - _ => return Err(Error::Message("Expected key to be a string".into())), - }; - let value = value.serialize(&mut **self)?; - match &mut self.pending_js_value.last_mut() { - Some(JsValue::Object(map)) => { - map.insert(key_as_string, value); - Ok(()) - } - _ => { - return Err(Error::Message( - "Inner pending object is not a JsValue::Object".into(), - )) - } - } + self.serialize_keyvalue_to_pending_map(key, value) } fn end(self) -> Result { - self.pending_js_value - .pop() - .ok_or(Error::Message("Inner pending object is None".into())) + self.end_pending_map() } } // }}} @@ -467,24 +479,11 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer { where T: ?Sized + Serialize, { - let value = value.serialize(&mut **self)?; - match &mut self.pending_js_value.last_mut() { - Some(JsValue::Object(map)) => { - map.insert(key.into(), value); - Ok(()) - } - _ => { - return Err(Error::Message( - "Inner pending object is not a JsValue::Object".into(), - )) - } - } + self.serialize_keyvalue_to_pending_map(key, value) } fn end(self) -> Result { - self.pending_js_value - .pop() - .ok_or(Error::Message("Inner pending object is None".into())) + self.end_pending_map() } } // }}} @@ -500,18 +499,7 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { where T: ?Sized + Serialize, { - let value = value.serialize(&mut **self)?; - match self.pending_js_value.last_mut() { - Some(JsValue::Object(map)) => { - map.insert(key.into(), value); - Ok(()) - } - _ => { - return Err(Error::Message( - "Inner pending value is not an object".into(), - )) - } - } + self.serialize_keyvalue_to_pending_map(key, value) } fn end(self) -> Result { @@ -519,13 +507,8 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { .pending_hashmap_key .take() .ok_or(Error::Message("The pending HashMap key is None".into()))?; - let value = self - .pending_js_value - .pop() - .ok_or(Error::Message("Inner pending value is None".into()))?; - let mut map = HashMap::new(); - map.insert(key, value); - Ok(JsValue::Object(map)) + let value = self.end_pending_map()?; + Ok(self.wrap_in_map_with_key(key, value)) } } // }}} From 52690ff4d3d91e8653a0bcc1c9d88d35ca8cb625 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Fri, 29 May 2020 22:40:29 -0600 Subject: [PATCH 05/15] Most primitives deserialize --- src/value/serde.rs | 209 +++++++++++++++++++++++++++++++-------------- 1 file changed, 146 insertions(+), 63 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 22afdff..1dba6c4 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -515,7 +515,7 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer { // ser tests {{{ #[test] -fn test_struct() { +fn test_ser_struct() { use serde::Serialize; #[derive(Serialize)] @@ -546,7 +546,7 @@ fn test_struct() { } #[test] -fn test_enum() { +fn test_ser_enum() { #[derive(Serialize)] enum E { Unit, @@ -587,12 +587,14 @@ fn test_enum() { // de {{{ pub struct Deserializer<'de> { - input: &'de JsValue, + pending_js_value: Vec<&'de JsValue>, } impl<'de> Deserializer<'de> { pub fn from_js_value(input: &'de JsValue) -> Self { - Deserializer { input } + Deserializer { + pending_js_value: vec![input], + } } } @@ -612,115 +614,164 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // match self.peek_char()? { - // 'n' => self.deserialize_unit(visitor), - // 't' | 'f' => self.deserialize_bool(visitor), - // '"' => self.deserialize_str(visitor), - // '0'..='9' => self.deserialize_u64(visitor), - // '-' => self.deserialize_i64(visitor), - // '[' => self.deserialize_seq(visitor), - // '{' => self.deserialize_map(visitor), - // _ => Err(Error::Syntax), - // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::Object(map)) => self.deserialize_map(visitor), + Some(JsValue::Array(v)) => self.deserialize_seq(visitor), + Some(JsValue::String(s)) => self.deserialize_string(visitor), + #[cfg(feature = "chrono")] + Some(JsValue::Date(d)) => todo!(), + #[cfg(feature = "num-bigint")] + Some(JsValue::BigInt(bi)) => todo!(), + Some(JsValue::Float(f)) => self.deserialize_f64(visitor), + Some(JsValue::Int(i)) => self.deserialize_i64(visitor), + Some(JsValue::Bool(b)) => self.deserialize_bool(visitor), + Some(JsValue::Null) => self.deserialize_option(visitor), + _ => return Err(Error::Message("Pending JS Value is invalid".into())), + } } fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_bool(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Bool(b)) => visitor.visit_bool(*b), + _ => Err(Error::Message("Expected bool".into())), + } } fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_i8(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_i8(*i as i8), + _ => Err(Error::Message("Expected i8".into())), + } } fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_i16(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_i16(*i as i16), + _ => Err(Error::Message("Expected i16".into())), + } } fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_i32(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_i32(*i as i32), + _ => Err(Error::Message("Expected i32".into())), + } } fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_i64(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_i64(*i as i64), + _ => Err(Error::Message("Expected i64".into())), + } } fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_u8(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_u8(*i as u8), + _ => Err(Error::Message("Expected u8".into())), + } } fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_u16(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_u16(*i as u16), + _ => Err(Error::Message("Expected u16".into())), + } } fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_u32(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_u32(*i as u32), + _ => Err(Error::Message("Expected u32".into())), + } } fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_u64(todo!()) + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_u64(*i as u64), + _ => Err(Error::Message("Expected u64".into())), + } } - fn deserialize_f32(self, _visitor: V) -> Result + fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_f32(*i as f32), + Some(JsValue::Float(f)) => visitor.visit_f32(*f as f32), + _ => Err(Error::Message("Expected f32".into())), + } } - fn deserialize_f64(self, _visitor: V) -> Result + fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + match self.pending_js_value.last() { + Some(JsValue::Int(i)) => visitor.visit_f64(*i as f64), + Some(JsValue::Float(f)) => visitor.visit_f64(*f as f64), + _ => Err(Error::Message("Expected f64".into())), + } } - fn deserialize_char(self, _visitor: V) -> Result + fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + match self.pending_js_value.last() { + Some(JsValue::String(s)) if s.len() == 1 => { + visitor.visit_char(s.chars().nth(0).unwrap() as char) + } + _ => Err(Error::Message("Expected char".into())), + } } fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de>, { - visitor.visit_borrowed_str(todo!()) + match self.pending_js_value.last() { + Some(JsValue::String(s)) => visitor.visit_str(s), + _ => Err(Error::Message("Expected str".into())), + } } fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de>, { - self.deserialize_str(visitor) + match self.pending_js_value.last() { + Some(JsValue::String(s)) => visitor.visit_string(s.clone()), + _ => Err(Error::Message("Expected String".into())), + } } fn deserialize_bytes(self, _visitor: V) -> Result @@ -749,26 +800,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // if self.input.starts_with("null") { - // self.input = &self.input["null".len()..]; - // visitor.visit_none() - // } else { - // visitor.visit_some(self) - // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::Null) => visitor.visit_none(), + _ => visitor.visit_some(self), + } } fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de>, { - // if self.input.starts_with("null") { - // self.input = &self.input["null".len()..]; - // visitor.visit_unit() - // } else { - // Err(Error::ExpectedNull) - // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::Null) => visitor.visit_none(), + _ => Err(Error::Message("Expected ()".into())), + } } fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result @@ -808,7 +853,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { // } else { // Err(Error::ExpectedArray) // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::Array(vec)) => todo!(), + _ => Err(Error::Message("Expected Array".into())), + } } // Tuples look just like sequences in JSON. Some formats may be able to @@ -857,7 +905,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { // } else { // Err(Error::ExpectedMap) // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::Object(map)) => todo!(), + _ => Err(Error::Message("Expected Object".into())), + } } // Structs look just like maps in JSON. @@ -937,21 +988,53 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { // }}} // de tests {{{ -// #[test] -// fn test_struct() { -// #[derive(Deserialize, PartialEq, Debug)] -// struct Test { -// int: u32, -// seq: Vec, -// } -// -// let j = r#"{"int":1,"seq":["a","b"]}"#; -// let expected = Test { -// int: 1, -// seq: vec!["a".to_owned(), "b".to_owned()], -// }; -// assert_eq!(expected, from_js_value(j).unwrap()); -// } +#[test] +fn test_de_primitives() { + let i: i8 = from_js_value(&JsValue::Int(12)).unwrap(); + assert_eq!(i, 12); + + let f: f32 = from_js_value(&JsValue::Int(12)).unwrap(); + assert_eq!(f, 12f32); + + let f: f32 = from_js_value(&JsValue::Float(3.14f64)).unwrap(); + assert_eq!(f, 3.14f32); + + let b: bool = from_js_value(&JsValue::Bool(true)).unwrap(); + assert_eq!(b, true); + + let j = JsValue::String("a".into()); + let s: String = from_js_value(&j).unwrap(); + assert_eq!(s, "a".to_string()); + + let j = JsValue::String("a".into()); + let s: &str = from_js_value(&j).unwrap(); + assert_eq!(s, "a"); +} + +#[test] +fn test_de_struct() { + #[derive(Deserialize, PartialEq, Debug)] + struct Test { + int: u32, + seq: Vec, + } + + let mut map = HashMap::new(); + map.insert("int".into(), JsValue::Int(1)); + map.insert( + "seq".into(), + JsValue::Array(vec![ + JsValue::String("a".into()), + JsValue::String("b".into()), + ]), + ); + let j = JsValue::Object(map); + let expected = Test { + int: 1, + seq: vec!["a".to_owned(), "b".to_owned()], + }; + assert_eq!(expected, from_js_value(&j).unwrap()); +} // // #[test] // fn test_enum() { From 50c63cee68672278cdc60d798efd1f52ec82b5ac Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Sat, 30 May 2020 21:56:07 -0600 Subject: [PATCH 06/15] Stub in SeqAccess/MapAccess for Deserializer --- src/value/serde.rs | 118 ++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 50 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 1dba6c4..7b0786f 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -774,28 +774,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } } - fn deserialize_bytes(self, _visitor: V) -> Result + fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + self.deserialize_seq(visitor) } - fn deserialize_byte_buf(self, _visitor: V) -> Result + fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>, { - unimplemented!() + self.deserialize_seq(visitor) } - // An absent optional is represented as the JSON `null` and a present - // optional is represented as just the contained value. - // - // As commented in `Serializer` implementation, this is a lossy - // representation. For example the values `Some(())` and `None` both - // serialize as just `null`. Unfortunately this is typically what people - // expect when working with JSON. Other formats are encouraged to behave - // more intelligently if possible. fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de>, @@ -840,23 +832,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // // Parse the opening bracket of the sequence. - // if self.next_char()? == '[' { - // // Give the visitor access to each element of the sequence. - // let value = visitor.visit_seq(CommaSeparated::new(&mut self))?; - // // Parse the closing bracket of the sequence. - // if self.next_char()? == ']' { - // Ok(value) - // } else { - // Err(Error::ExpectedArrayEnd) - // } - // } else { - // Err(Error::ExpectedArray) - // } - match self.pending_js_value.last() { - Some(JsValue::Array(vec)) => todo!(), - _ => Err(Error::Message("Expected Array".into())), - } + visitor.visit_seq(NestedAccess::new(&mut self)) } // Tuples look just like sequences in JSON. Some formats may be able to @@ -892,23 +868,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // // Parse the opening brace of the map. - // if self.next_char()? == '{' { - // // Give the visitor access to each entry of the map. - // let value = visitor.visit_map(CommaSeparated::new(&mut self))?; - // // Parse the closing brace of the map. - // if self.next_char()? == '}' { - // Ok(value) - // } else { - // Err(Error::ExpectedMapEnd) - // } - // } else { - // Err(Error::ExpectedMap) - // } - match self.pending_js_value.last() { - Some(JsValue::Object(map)) => todo!(), - _ => Err(Error::Message("Expected Object".into())), - } + visitor.visit_map(NestedAccess::new(&mut *self)) } // Structs look just like maps in JSON. @@ -987,6 +947,68 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } // }}} +// ArrayAccess {{{ +struct NestedAccess<'a, 'de: 'a> { + de: &'a mut Deserializer<'de>, + idx: usize, +} + +impl<'a, 'de> NestedAccess<'a, 'de> { + pub fn new(de: &'a mut Deserializer<'de>) -> Self { + NestedAccess { de, idx: 0 } + } +} + +impl<'de, 'a> SeqAccess<'de> for NestedAccess<'a, 'de> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result> + where + T: DeserializeSeed<'de>, + { + let vec = match self.de.pending_js_value.last() { + Some(JsValue::Array(vec)) => vec, + _ => todo!(), + }; + if self.idx >= vec.len() { + Ok(None) + } else { + self.de.pending_js_value.push(&vec[self.idx]); + self.idx += 1; + let item = seed.deserialize(&mut *self.de)?; //vec[self.idx]; + self.de.pending_js_value.pop(); + Ok(Some(item)) + } + } +} + +impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result> + where + K: DeserializeSeed<'de>, + { + todo!() + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: DeserializeSeed<'de>, + { + todo!() + } + + fn next_entry_seed(&mut self, kseed: K, vseed: V) -> Result> + where + K: DeserializeSeed<'de>, + V: DeserializeSeed<'de>, + { + todo!() + } +} +// }}} + // de tests {{{ #[test] fn test_de_primitives() { @@ -1005,10 +1027,6 @@ fn test_de_primitives() { let j = JsValue::String("a".into()); let s: String = from_js_value(&j).unwrap(); assert_eq!(s, "a".to_string()); - - let j = JsValue::String("a".into()); - let s: &str = from_js_value(&j).unwrap(); - assert_eq!(s, "a"); } #[test] From 7669092f52a0ad6b8771cbd35b7496d24c120370 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Mon, 1 Jun 2020 16:39:25 -0600 Subject: [PATCH 07/15] One error down, one to go. --- src/value/serde.rs | 59 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 7b0786f..7b45e98 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -947,18 +947,24 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { } // }}} -// ArrayAccess {{{ +// NestedAccess {{{ struct NestedAccess<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, idx: usize, + hash_iter: Option>, } impl<'a, 'de> NestedAccess<'a, 'de> { pub fn new(de: &'a mut Deserializer<'de>) -> Self { - NestedAccess { de, idx: 0 } + NestedAccess { + de, + idx: 0, + hash_iter: None, + } } } +// impl SeqAccess for NestedAccess {{{ impl<'de, 'a> SeqAccess<'de> for NestedAccess<'a, 'de> { type Error = Error; @@ -981,7 +987,9 @@ impl<'de, 'a> SeqAccess<'de> for NestedAccess<'a, 'de> { } } } +// }}} +// impl MapAccess for NestedAccess {{{ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { type Error = Error; @@ -989,25 +997,52 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { where K: DeserializeSeed<'de>, { - todo!() + let map = match self.de.pending_js_value.last() { + Some(JsValue::Object(map)) => map, + _ => return Err(Error::Message("Expected JsValue::Object".into())), + }; + let mut iter = match self.hash_iter.as_mut() { + Some(i) => i.peekable(), + None => { + let i = map.iter(); + self.hash_iter = Some(i); + self.hash_iter.as_mut().unwrap().peekable() + } + }; + match iter.peek() { + Some((k, _)) => { + let k = (*k).clone(); + let result = seed.deserialize(k.into_deserializer())?; + Ok(Some(result)) + } + None => Ok(None), + } } fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { - todo!() - } - - fn next_entry_seed(&mut self, kseed: K, vseed: V) -> Result> - where - K: DeserializeSeed<'de>, - V: DeserializeSeed<'de>, - { - todo!() + let map = match self.de.pending_js_value.last() { + Some(JsValue::Object(map)) => map, + _ => unreachable!(), + }; + let mut iter = match self.hash_iter.as_mut() { + Some(i) => i, + None => unreachable!(), + }; + let value = match iter.next() { + Some((_k, v)) => v, + None => unreachable!(), + }; + self.de.pending_js_value.push(value); + let result = seed.deserialize(self.de)?; + self.de.pending_js_value.pop(); + Ok(result) } } // }}} +// }}} // de tests {{{ #[test] From d5c080a8f4dc9ceba7cc9a2f0ef162b220528d05 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Wed, 3 Jun 2020 21:41:16 -0600 Subject: [PATCH 08/15] It compiles again --- src/value/serde.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 7b45e98..b0465c2 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -951,7 +951,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { struct NestedAccess<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, idx: usize, - hash_iter: Option>, + hash_iter: Option>, } impl<'a, 'de> NestedAccess<'a, 'de> { @@ -1036,7 +1036,7 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { None => unreachable!(), }; self.de.pending_js_value.push(value); - let result = seed.deserialize(self.de)?; + let result = seed.deserialize(&mut *self.de)?; self.de.pending_js_value.pop(); Ok(result) } From 08a9e70f675d0e3b62c65c81be6283ac267366d7 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Wed, 3 Jun 2020 21:51:47 -0600 Subject: [PATCH 09/15] Better deserialization --- src/value/serde.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/value/serde.rs b/src/value/serde.rs index b0465c2..a87d732 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -646,6 +646,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_i8(*i as i8), + Some(JsValue::Float(f)) => visitor.visit_i8(*f as i8), _ => Err(Error::Message("Expected i8".into())), } } @@ -656,6 +657,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_i16(*i as i16), + Some(JsValue::Float(f)) => visitor.visit_i16(*f as i16), _ => Err(Error::Message("Expected i16".into())), } } @@ -666,6 +668,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_i32(*i as i32), + Some(JsValue::Float(f)) => visitor.visit_i32(*f as i32), _ => Err(Error::Message("Expected i32".into())), } } @@ -676,6 +679,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_i64(*i as i64), + Some(JsValue::Float(f)) => visitor.visit_i64(*f as i64), _ => Err(Error::Message("Expected i64".into())), } } @@ -686,6 +690,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_u8(*i as u8), + Some(JsValue::Float(f)) => visitor.visit_u8(*f as u8), _ => Err(Error::Message("Expected u8".into())), } } @@ -696,6 +701,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_u16(*i as u16), + Some(JsValue::Float(f)) => visitor.visit_u16(*f as u16), _ => Err(Error::Message("Expected u16".into())), } } @@ -706,6 +712,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_u32(*i as u32), + Some(JsValue::Float(f)) => visitor.visit_u32(*f as u32), _ => Err(Error::Message("Expected u32".into())), } } @@ -716,6 +723,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::Int(i)) => visitor.visit_u64(*i as u64), + Some(JsValue::Float(f)) => visitor.visit_u64(*f as u64), _ => Err(Error::Message("Expected u64".into())), } } From 6d4d212cb293654b7c155c5b32327947e6786663 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Wed, 3 Jun 2020 22:12:51 -0600 Subject: [PATCH 10/15] Woohoo! Can deserialize structs! --- src/value/serde.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index a87d732..2abc1b0 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -603,7 +603,9 @@ where T: Deserialize<'a>, { let mut deserializer = Deserializer::from_js_value(val); - T::deserialize(&mut deserializer) + let result = T::deserialize(&mut deserializer)?; + assert_eq!(deserializer.pending_js_value.len(), 1); + Ok(result) } // de::Deserializer {{{ @@ -959,7 +961,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { struct NestedAccess<'a, 'de: 'a> { de: &'a mut Deserializer<'de>, idx: usize, - hash_iter: Option>, + hash_iter: Option>>, } impl<'a, 'de> NestedAccess<'a, 'de> { @@ -1010,11 +1012,11 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { _ => return Err(Error::Message("Expected JsValue::Object".into())), }; let mut iter = match self.hash_iter.as_mut() { - Some(i) => i.peekable(), + Some(i) => i, None => { - let i = map.iter(); + let i = map.iter().peekable(); self.hash_iter = Some(i); - self.hash_iter.as_mut().unwrap().peekable() + self.hash_iter.as_mut().unwrap() } }; match iter.peek() { @@ -1096,7 +1098,7 @@ fn test_de_struct() { }; assert_eq!(expected, from_js_value(&j).unwrap()); } -// + // #[test] // fn test_enum() { // #[derive(Deserialize, PartialEq, Debug)] From 2ca1812189f10dda18942b4dc48b37c85401f1a8 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Wed, 3 Jun 2020 22:19:30 -0600 Subject: [PATCH 11/15] Clippy said so --- src/value/serde.rs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 2abc1b0..ef62aac 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -1,15 +1,12 @@ // imports {{{ -use std; -use std::collections::HashMap; -use std::fmt::{self, Display}; -use std::ops::{AddAssign, MulAssign, Neg}; - use serde::de::{ self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor, }; use serde::Deserialize; use serde::{ser, Serialize}; +use std::collections::HashMap; +use std::fmt::{self, Display}; use super::JsValue; // }}} @@ -50,7 +47,7 @@ impl de::Error for Error { } impl Display for Error { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { match self { _ => unimplemented!(), } @@ -88,11 +85,9 @@ impl Serializer { map.insert(key_as_string, value); Ok(()) } - _ => { - return Err(Error::Message( - "Inner pending object is not a JsValue::Object".into(), - )) - } + _ => Err(Error::Message( + "Inner pending object is not a JsValue::Object".into(), + )), } } @@ -112,7 +107,7 @@ impl Serializer { arr.push(value); Ok(()) } - _ => return Err(Error::Message("Inner pending value is not an array".into())), + _ => Err(Error::Message("Inner pending value is not an array".into())), } } @@ -628,7 +623,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { Some(JsValue::Int(i)) => self.deserialize_i64(visitor), Some(JsValue::Bool(b)) => self.deserialize_bool(visitor), Some(JsValue::Null) => self.deserialize_option(visitor), - _ => return Err(Error::Message("Pending JS Value is invalid".into())), + _ => Err(Error::Message("Pending JS Value is invalid".into())), } } @@ -758,7 +753,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { { match self.pending_js_value.last() { Some(JsValue::String(s)) if s.len() == 1 => { - visitor.visit_char(s.chars().nth(0).unwrap() as char) + visitor.visit_char(s.chars().next().unwrap() as char) } _ => Err(Error::Message("Expected char".into())), } From 8136e0b982d7fb0ec6f9d998082eae480d27cdc8 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Sat, 20 Jun 2020 23:32:06 -0600 Subject: [PATCH 12/15] It doesn't run, but it compiles --- src/value/serde.rs | 138 ++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 47 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index ef62aac..272bcc5 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -763,9 +763,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { + let last = self.pending_js_value.last(); + match last { Some(JsValue::String(s)) => visitor.visit_str(s), - _ => Err(Error::Message("Expected str".into())), + _ => Err(Error::Message(format!("Expected str, got: {:?}", last))), } } @@ -869,7 +870,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { // Much like `deserialize_seq` but calls the visitors `visit_map` method // with a `MapAccess` implementation, rather than the visitor's `visit_seq` // method with a `SeqAccess` implementation. - fn deserialize_map(mut self, visitor: V) -> Result + fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de>, { @@ -903,22 +904,18 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - // if self.peek_char()? == '"' { - // // Visit a unit variant. - // visitor.visit_enum(self.parse_string()?.into_deserializer()) - // } else if self.next_char()? == '{' { - // // Visit a newtype variant, tuple variant, or struct variant. - // let value = visitor.visit_enum(Enum::new(self))?; - // // Parse the matching close brace. - // if self.next_char()? == '}' { - // Ok(value) - // } else { - // Err(Error::ExpectedMapEnd) - // } - // } else { - // Err(Error::ExpectedEnum) - // } - todo!() + match self.pending_js_value.last() { + Some(JsValue::String(name)) => visitor.visit_enum(name.clone().into_deserializer()), + Some(js_value @ JsValue::Object(..)) => { + // re-borrow, to make the borrow-checker happy: + let js_value: &JsValue = *self.pending_js_value.last().unwrap(); + self.pending_js_value.push(dbg!(js_value)); + let result = visitor.visit_enum(&mut *self); + self.pending_js_value.pop(); + result + } + _ => todo!(), + } } // An identifier in Serde is the type that identifies a field of a struct or @@ -1006,7 +1003,7 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { Some(JsValue::Object(map)) => map, _ => return Err(Error::Message("Expected JsValue::Object".into())), }; - let mut iter = match self.hash_iter.as_mut() { + let iter = match self.hash_iter.as_mut() { Some(i) => i, None => { let i = map.iter().peekable(); @@ -1032,7 +1029,7 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { Some(JsValue::Object(map)) => map, _ => unreachable!(), }; - let mut iter = match self.hash_iter.as_mut() { + let iter = match self.hash_iter.as_mut() { Some(i) => i, None => unreachable!(), }; @@ -1047,6 +1044,47 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { } } // }}} + +// }}} + +// EnumAccess {{{ +impl<'de> EnumAccess<'de> for &mut Deserializer<'de> { + type Error = Error; + type Variant = Self; + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> + where + V: DeserializeSeed<'de>, + { + Ok((seed.deserialize(&mut *self)?, self)) + } +} +// }}} + +// VariantAccess {{{ +impl<'de> VariantAccess<'de> for &mut Deserializer<'de> { + type Error = Error; + fn unit_variant(self) -> Result<()> { + todo!("unit_variant") + } + fn tuple_variant(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + todo!("tuple_variant") + } + fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result + where + V: Visitor<'de>, + { + todo!("struct_variant") + } + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + todo!("newtype_variant_seed") + } +} // }}} // de tests {{{ @@ -1067,6 +1105,10 @@ fn test_de_primitives() { let j = JsValue::String("a".into()); let s: String = from_js_value(&j).unwrap(); assert_eq!(s, "a".to_string()); + + // let dt = chrono::Utc::now(); + // let d: chrono::DateTime<_> = from_js_value(&JsValue::Date(dt)).unwrap(); + // assert_eq!(d, dt); } #[test] @@ -1094,31 +1136,33 @@ fn test_de_struct() { assert_eq!(expected, from_js_value(&j).unwrap()); } -// #[test] -// fn test_enum() { -// #[derive(Deserialize, PartialEq, Debug)] -// enum E { -// Unit, -// Newtype(u32), -// Tuple(u32, u32), -// Struct { a: u32 }, -// } -// -// let j = r#""Unit""#; -// let expected = E::Unit; -// assert_eq!(expected, from_js_value(j).unwrap()); -// -// let j = r#"{"Newtype":1}"#; -// let expected = E::Newtype(1); -// assert_eq!(expected, from_js_value(j).unwrap()); -// -// let j = r#"{"Tuple":[1,2]}"#; -// let expected = E::Tuple(1, 2); -// assert_eq!(expected, from_js_value(j).unwrap()); -// -// let j = r#"{"Struct":{"a":1}}"#; -// let expected = E::Struct { a: 1 }; -// assert_eq!(expected, from_js_value(j).unwrap()); -// } +#[test] +fn test_de_enum() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + Unit, + Newtype(u32), + Tuple(u32, u32), + Struct { a: u32 }, + } + + let j = JsValue::String("Unit".into()); + let expected = E::Unit; + assert_eq!(expected, from_js_value(&j).unwrap()); + + let mut map = HashMap::new(); + map.insert("Newtype".into(), JsValue::Int(1)); + let j = JsValue::Object(map); + let expected = E::Newtype(1); + assert_eq!(expected, from_js_value(&j).unwrap()); + // + // let j = r#"{"Tuple":[1,2]}"#; + // let expected = E::Tuple(1, 2); + // assert_eq!(expected, from_js_value(j).unwrap()); + // + // let j = r#"{"Struct":{"a":1}}"#; + // let expected = E::Struct { a: 1 }; + // assert_eq!(expected, from_js_value(j).unwrap()); +} // }}} // }}} From daeae6148a8c402dae97da133b88b73dd25fbf24 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Sat, 27 Jun 2020 22:12:17 -0600 Subject: [PATCH 13/15] serde: Deserializes newtype structs --- src/value/serde.rs | 182 +++++++++++++++++++++++++++------------------ 1 file changed, 108 insertions(+), 74 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 272bcc5..87d280e 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -581,14 +581,19 @@ fn test_ser_enum() { // }}} // de {{{ +#[derive(Debug)] +enum PendingValue<'de> { + JsValue(&'de JsValue), + String(String), +} pub struct Deserializer<'de> { - pending_js_value: Vec<&'de JsValue>, + pending_value: Vec>, } impl<'de> Deserializer<'de> { pub fn from_js_value(input: &'de JsValue) -> Self { Deserializer { - pending_js_value: vec![input], + pending_value: vec![PendingValue::JsValue(input)], } } } @@ -599,7 +604,7 @@ where { let mut deserializer = Deserializer::from_js_value(val); let result = T::deserialize(&mut deserializer)?; - assert_eq!(deserializer.pending_js_value.len(), 1); + assert_eq!(deserializer.pending_value.len(), 1); Ok(result) } @@ -611,18 +616,19 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Object(map)) => self.deserialize_map(visitor), - Some(JsValue::Array(v)) => self.deserialize_seq(visitor), - Some(JsValue::String(s)) => self.deserialize_string(visitor), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Object(map))) => self.deserialize_map(visitor), + Some(PendingValue::JsValue(JsValue::Array(v))) => self.deserialize_seq(visitor), + Some(PendingValue::JsValue(JsValue::String(s))) => self.deserialize_string(visitor), + Some(PendingValue::String(s)) => self.deserialize_string(visitor), #[cfg(feature = "chrono")] - Some(JsValue::Date(d)) => todo!(), + Some(PendingValue::JsValue(JsValue::Date(d))) => todo!(), #[cfg(feature = "num-bigint")] - Some(JsValue::BigInt(bi)) => todo!(), - Some(JsValue::Float(f)) => self.deserialize_f64(visitor), - Some(JsValue::Int(i)) => self.deserialize_i64(visitor), - Some(JsValue::Bool(b)) => self.deserialize_bool(visitor), - Some(JsValue::Null) => self.deserialize_option(visitor), + Some(PendingValue::JsValue(JsValue::BigInt(bi))) => todo!(), + Some(PendingValue::JsValue(JsValue::Float(f))) => self.deserialize_f64(visitor), + Some(PendingValue::JsValue(JsValue::Int(i))) => self.deserialize_i64(visitor), + Some(PendingValue::JsValue(JsValue::Bool(b))) => self.deserialize_bool(visitor), + Some(PendingValue::JsValue(JsValue::Null)) => self.deserialize_option(visitor), _ => Err(Error::Message("Pending JS Value is invalid".into())), } } @@ -631,8 +637,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Bool(b)) => visitor.visit_bool(*b), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Bool(b))) => visitor.visit_bool(*b), _ => Err(Error::Message("Expected bool".into())), } } @@ -641,9 +647,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_i8(*i as i8), - Some(JsValue::Float(f)) => visitor.visit_i8(*f as i8), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_i8(*i as i8), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_i8(*f as i8), _ => Err(Error::Message("Expected i8".into())), } } @@ -652,9 +658,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_i16(*i as i16), - Some(JsValue::Float(f)) => visitor.visit_i16(*f as i16), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_i16(*i as i16), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_i16(*f as i16), _ => Err(Error::Message("Expected i16".into())), } } @@ -663,9 +669,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_i32(*i as i32), - Some(JsValue::Float(f)) => visitor.visit_i32(*f as i32), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_i32(*i as i32), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_i32(*f as i32), _ => Err(Error::Message("Expected i32".into())), } } @@ -674,9 +680,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_i64(*i as i64), - Some(JsValue::Float(f)) => visitor.visit_i64(*f as i64), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_i64(*i as i64), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_i64(*f as i64), _ => Err(Error::Message("Expected i64".into())), } } @@ -685,9 +691,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_u8(*i as u8), - Some(JsValue::Float(f)) => visitor.visit_u8(*f as u8), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_u8(*i as u8), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_u8(*f as u8), _ => Err(Error::Message("Expected u8".into())), } } @@ -696,9 +702,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_u16(*i as u16), - Some(JsValue::Float(f)) => visitor.visit_u16(*f as u16), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_u16(*i as u16), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_u16(*f as u16), _ => Err(Error::Message("Expected u16".into())), } } @@ -707,9 +713,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_u32(*i as u32), - Some(JsValue::Float(f)) => visitor.visit_u32(*f as u32), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_u32(*i as u32), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_u32(*f as u32), _ => Err(Error::Message("Expected u32".into())), } } @@ -718,9 +724,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_u64(*i as u64), - Some(JsValue::Float(f)) => visitor.visit_u64(*f as u64), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_u64(*i as u64), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_u64(*f as u64), _ => Err(Error::Message("Expected u64".into())), } } @@ -729,9 +735,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_f32(*i as f32), - Some(JsValue::Float(f)) => visitor.visit_f32(*f as f32), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_f32(*i as f32), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_f32(*f as f32), _ => Err(Error::Message("Expected f32".into())), } } @@ -740,9 +746,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Int(i)) => visitor.visit_f64(*i as f64), - Some(JsValue::Float(f)) => visitor.visit_f64(*f as f64), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Int(i))) => visitor.visit_f64(*i as f64), + Some(PendingValue::JsValue(JsValue::Float(f))) => visitor.visit_f64(*f as f64), _ => Err(Error::Message("Expected f64".into())), } } @@ -751,8 +757,11 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::String(s)) if s.len() == 1 => { + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::String(s))) if s.len() == 1 => { + visitor.visit_char(s.chars().next().unwrap() as char) + } + Some(PendingValue::String(s)) if s.len() == 1 => { visitor.visit_char(s.chars().next().unwrap() as char) } _ => Err(Error::Message("Expected char".into())), @@ -763,9 +772,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - let last = self.pending_js_value.last(); + let last = self.pending_value.last(); match last { - Some(JsValue::String(s)) => visitor.visit_str(s), + Some(PendingValue::JsValue(JsValue::String(s))) => visitor.visit_str(s), + Some(PendingValue::String(s)) => visitor.visit_str(s), _ => Err(Error::Message(format!("Expected str, got: {:?}", last))), } } @@ -774,8 +784,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::String(s)) => visitor.visit_string(s.clone()), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::String(s))) => visitor.visit_string(s.clone()), + Some(PendingValue::String(s)) => visitor.visit_str(s), _ => Err(Error::Message("Expected String".into())), } } @@ -798,8 +809,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Null) => visitor.visit_none(), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Null)) => visitor.visit_none(), _ => visitor.visit_some(self), } } @@ -808,8 +819,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::Null) => visitor.visit_none(), + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Null)) => visitor.visit_none(), _ => Err(Error::Message("Expected ()".into())), } } @@ -904,14 +915,18 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { where V: Visitor<'de>, { - match self.pending_js_value.last() { - Some(JsValue::String(name)) => visitor.visit_enum(name.clone().into_deserializer()), - Some(js_value @ JsValue::Object(..)) => { + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::String(name))) => visitor.visit_enum(name.clone().into_deserializer()), + Some(PendingValue::String(name)) => visitor.visit_enum(name.clone().into_deserializer()), + Some(js_value @ PendingValue::JsValue(JsValue::Object(..))) => { // re-borrow, to make the borrow-checker happy: - let js_value: &JsValue = *self.pending_js_value.last().unwrap(); - self.pending_js_value.push(dbg!(js_value)); + let js_value: &JsValue = *match self.pending_value.last() { + Some(PendingValue::JsValue(js_value)) => js_value, + _ => unreachable!(), + }; + self.pending_value.push(PendingValue::JsValue(dbg!(js_value))); let result = visitor.visit_enum(&mut *self); - self.pending_js_value.pop(); + self.pending_value.pop(); result } _ => todo!(), @@ -974,17 +989,17 @@ impl<'de, 'a> SeqAccess<'de> for NestedAccess<'a, 'de> { where T: DeserializeSeed<'de>, { - let vec = match self.de.pending_js_value.last() { - Some(JsValue::Array(vec)) => vec, + let vec = match self.de.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Array(vec))) => vec, _ => todo!(), }; if self.idx >= vec.len() { Ok(None) } else { - self.de.pending_js_value.push(&vec[self.idx]); + self.de.pending_value.push(PendingValue::JsValue(&vec[self.idx])); self.idx += 1; let item = seed.deserialize(&mut *self.de)?; //vec[self.idx]; - self.de.pending_js_value.pop(); + self.de.pending_value.pop(); Ok(Some(item)) } } @@ -999,8 +1014,8 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { where K: DeserializeSeed<'de>, { - let map = match self.de.pending_js_value.last() { - Some(JsValue::Object(map)) => map, + let map = match self.de.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Object(map))) => map, _ => return Err(Error::Message("Expected JsValue::Object".into())), }; let iter = match self.hash_iter.as_mut() { @@ -1025,8 +1040,8 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { where V: DeserializeSeed<'de>, { - let map = match self.de.pending_js_value.last() { - Some(JsValue::Object(map)) => map, + let map = match self.de.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Object(map))) => map, _ => unreachable!(), }; let iter = match self.hash_iter.as_mut() { @@ -1037,9 +1052,9 @@ impl<'de, 'a> MapAccess<'de> for NestedAccess<'a, 'de> { Some((_k, v)) => v, None => unreachable!(), }; - self.de.pending_js_value.push(value); + self.de.pending_value.push(PendingValue::JsValue(value)); let result = seed.deserialize(&mut *self.de)?; - self.de.pending_js_value.pop(); + self.de.pending_value.pop(); Ok(result) } } @@ -1055,7 +1070,17 @@ impl<'de> EnumAccess<'de> for &mut Deserializer<'de> { where V: DeserializeSeed<'de>, { - Ok((seed.deserialize(&mut *self)?, self)) + match self.pending_value.last() { + Some(PendingValue::JsValue(JsValue::Object(map))) => { + let (k, v) = map.iter().next().unwrap(); + self.pending_value.push(PendingValue::String(k.clone())); + let result = seed.deserialize(&mut *self)?; + self.pending_value.pop(); + self.pending_value.push(PendingValue::JsValue(v)); + Ok((result, self)) + } + _ => panic!("Can't handle this yet...") + } } } // }}} @@ -1078,16 +1103,20 @@ impl<'de> VariantAccess<'de> for &mut Deserializer<'de> { { todo!("struct_variant") } + fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>, { - todo!("newtype_variant_seed") + let result = seed.deserialize(&mut *self)?; + self.pending_value.pop(); + Ok(result) } } // }}} // de tests {{{ +// test_de_primitives {{{ #[test] fn test_de_primitives() { let i: i8 = from_js_value(&JsValue::Int(12)).unwrap(); @@ -1110,7 +1139,9 @@ fn test_de_primitives() { // let d: chrono::DateTime<_> = from_js_value(&JsValue::Date(dt)).unwrap(); // assert_eq!(d, dt); } +// }}} +// test_de_struct {{{ #[test] fn test_de_struct() { #[derive(Deserialize, PartialEq, Debug)] @@ -1135,7 +1166,9 @@ fn test_de_struct() { }; assert_eq!(expected, from_js_value(&j).unwrap()); } +// }}} +// test_de_enum {{{ #[test] fn test_de_enum() { #[derive(Deserialize, PartialEq, Debug)] @@ -1155,7 +1188,7 @@ fn test_de_enum() { let j = JsValue::Object(map); let expected = E::Newtype(1); assert_eq!(expected, from_js_value(&j).unwrap()); - // + // let j = r#"{"Tuple":[1,2]}"#; // let expected = E::Tuple(1, 2); // assert_eq!(expected, from_js_value(j).unwrap()); @@ -1166,3 +1199,4 @@ fn test_de_enum() { } // }}} // }}} +// }}} From 0e726dceb98aefc6586bb6e612e1a418ba9ef84c Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Sat, 27 Jun 2020 22:21:07 -0600 Subject: [PATCH 14/15] serde: All tests pass! (basic functionality working...need more tests) --- src/value/serde.rs | 50 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index 87d280e..fa0fff1 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -916,15 +916,20 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { V: Visitor<'de>, { match self.pending_value.last() { - Some(PendingValue::JsValue(JsValue::String(name))) => visitor.visit_enum(name.clone().into_deserializer()), - Some(PendingValue::String(name)) => visitor.visit_enum(name.clone().into_deserializer()), + Some(PendingValue::JsValue(JsValue::String(name))) => { + visitor.visit_enum(name.clone().into_deserializer()) + } + Some(PendingValue::String(name)) => { + visitor.visit_enum(name.clone().into_deserializer()) + } Some(js_value @ PendingValue::JsValue(JsValue::Object(..))) => { // re-borrow, to make the borrow-checker happy: let js_value: &JsValue = *match self.pending_value.last() { Some(PendingValue::JsValue(js_value)) => js_value, _ => unreachable!(), }; - self.pending_value.push(PendingValue::JsValue(dbg!(js_value))); + self.pending_value + .push(PendingValue::JsValue(dbg!(js_value))); let result = visitor.visit_enum(&mut *self); self.pending_value.pop(); result @@ -996,7 +1001,9 @@ impl<'de, 'a> SeqAccess<'de> for NestedAccess<'a, 'de> { if self.idx >= vec.len() { Ok(None) } else { - self.de.pending_value.push(PendingValue::JsValue(&vec[self.idx])); + self.de + .pending_value + .push(PendingValue::JsValue(&vec[self.idx])); self.idx += 1; let item = seed.deserialize(&mut *self.de)?; //vec[self.idx]; self.de.pending_value.pop(); @@ -1079,7 +1086,7 @@ impl<'de> EnumAccess<'de> for &mut Deserializer<'de> { self.pending_value.push(PendingValue::JsValue(v)); Ok((result, self)) } - _ => panic!("Can't handle this yet...") + _ => panic!("Can't handle this yet..."), } } } @@ -1089,19 +1096,23 @@ impl<'de> EnumAccess<'de> for &mut Deserializer<'de> { impl<'de> VariantAccess<'de> for &mut Deserializer<'de> { type Error = Error; fn unit_variant(self) -> Result<()> { - todo!("unit_variant") + Err(Error::ExpectedString) } fn tuple_variant(self, len: usize, visitor: V) -> Result where V: Visitor<'de>, { - todo!("tuple_variant") + let result = de::Deserializer::deserialize_seq(&mut *self, visitor)?; + self.pending_value.pop(); + Ok(result) } fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { - todo!("struct_variant") + let result = de::Deserializer::deserialize_map(&mut *self, visitor)?; + self.pending_value.pop(); + Ok(result) } fn newtype_variant_seed(self, seed: T) -> Result @@ -1189,13 +1200,22 @@ fn test_de_enum() { let expected = E::Newtype(1); assert_eq!(expected, from_js_value(&j).unwrap()); - // let j = r#"{"Tuple":[1,2]}"#; - // let expected = E::Tuple(1, 2); - // assert_eq!(expected, from_js_value(j).unwrap()); - // - // let j = r#"{"Struct":{"a":1}}"#; - // let expected = E::Struct { a: 1 }; - // assert_eq!(expected, from_js_value(j).unwrap()); + let mut map = HashMap::new(); + map.insert( + "Tuple".into(), + JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]), + ); + let j = JsValue::Object(map); + let expected = E::Tuple(1, 2); + assert_eq!(expected, from_js_value(&j).unwrap()); + + let mut inner_map = HashMap::new(); + inner_map.insert("a".into(), JsValue::Int(1)); + let mut map = HashMap::new(); + map.insert("Struct".into(), JsValue::Object(inner_map)); + let j = JsValue::Object(map); + let expected = E::Struct { a: 1 }; + assert_eq!(expected, from_js_value(&j).unwrap()); } // }}} // }}} From 38d786fac583996a60ce3a2c7201335e735aa5c9 Mon Sep 17 00:00:00 2001 From: Jonathan Apodaca Date: Mon, 13 Jul 2020 20:30:59 -0600 Subject: [PATCH 15/15] serde: Implement serialize_tuple_struct --- src/value/serde.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/value/serde.rs b/src/value/serde.rs index fa0fff1..9332f55 100644 --- a/src/value/serde.rs +++ b/src/value/serde.rs @@ -373,17 +373,21 @@ impl<'a> ser::SerializeTupleStruct for &'a mut Serializer { where T: ?Sized + Serialize, { - // if !self.output.ends_with('[') { - // self.output += ","; - // } - // value.serialize(&mut **self) - todo!() + let serialized = value.serialize(&mut **self)?; + match self.pending_js_value.last_mut() { + Some(JsValue::Array(vec)) => { + vec.push(serialized); + Ok(()) + } + _ => return Err(Error::Message(format!("Expected pending to be an Array"))), + } } fn end(self) -> Result { - // self.output += "]"; - // Ok(()) - todo!() + match self.pending_js_value.pop() { + Some(v) => Ok(v), + None => Err(Error::Message(format!("No pending value"))), + } } } // }}} @@ -538,6 +542,13 @@ fn test_ser_struct() { let tuple = (1, 2); let expected = JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]); assert_eq!(to_js_value(&tuple).unwrap(), expected); + + #[derive(Serialize)] + struct TestTupleStruct(u32, u32); + + let js_value = to_js_value(&TestTupleStruct(1, 2)).unwrap(); + let expected = JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]); + assert_eq!(js_value, expected); } #[test] @@ -1176,6 +1187,12 @@ fn test_de_struct() { seq: vec!["a".to_owned(), "b".to_owned()], }; assert_eq!(expected, from_js_value(&j).unwrap()); + + #[derive(Deserialize, PartialEq, Debug)] + struct TestTupleStruct(u32, u32); + + let j = JsValue::Array(vec![JsValue::Int(1), JsValue::Int(2)]); + assert_eq!(TestTupleStruct(1, 2), from_js_value(&j).unwrap()); } // }}}