diff --git a/value/src/de.rs b/value/src/deserializer.rs similarity index 96% rename from value/src/de.rs rename to value/src/deserializer.rs index 33d921ff..0113b72b 100644 --- a/value/src/de.rs +++ b/value/src/deserializer.rs @@ -14,18 +14,21 @@ use serde::forward_to_deserialize_any; pub struct DeserializerError(String); impl de::Error for DeserializerError { + #[inline] fn custom(msg: T) -> Self { DeserializerError(msg.to_string()) } } impl std::error::Error for DeserializerError { + #[inline] fn description(&self) -> &str { "Value deserializer error" } } impl fmt::Display for DeserializerError { + #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { DeserializerError(msg) => write!(f, "{}", msg), @@ -34,18 +37,21 @@ impl fmt::Display for DeserializerError { } impl From for DeserializerError { + #[inline] fn from(e: de::value::Error) -> DeserializerError { DeserializerError(e.to_string()) } } impl ConstValue { + #[inline] fn unexpected(&self) -> Unexpected { match self { ConstValue::Null => Unexpected::Unit, ConstValue::Number(_) => Unexpected::Other("number"), ConstValue::String(v) => Unexpected::Str(v), ConstValue::Boolean(v) => Unexpected::Bool(*v), + ConstValue::Binary(v) => Unexpected::Bytes(v), ConstValue::Enum(v) => Unexpected::Str(v), ConstValue::List(_) => Unexpected::Seq, ConstValue::Object(_) => Unexpected::Map, @@ -95,6 +101,7 @@ where impl<'de> de::Deserializer<'de> for ConstValue { type Error = DeserializerError; + #[inline] fn deserialize_any(self, visitor: V) -> Result<>::Value, Self::Error> where V: Visitor<'de>, @@ -106,6 +113,7 @@ impl<'de> de::Deserializer<'de> for ConstValue { .map_err(|err| DeserializerError(err.to_string())), ConstValue::String(v) => visitor.visit_str(&v), ConstValue::Boolean(v) => visitor.visit_bool(v), + ConstValue::Binary(bytes) => visitor.visit_byte_buf(bytes), ConstValue::Enum(v) => visitor.visit_str(v.as_str()), ConstValue::List(v) => visit_array(v, visitor), ConstValue::Object(v) => visit_object(v, visitor), @@ -118,6 +126,7 @@ impl<'de> de::Deserializer<'de> for ConstValue { tuple_struct map struct identifier ignored_any } + #[inline] fn deserialize_option(self, visitor: V) -> Result<>::Value, Self::Error> where V: Visitor<'de>, @@ -128,6 +137,7 @@ impl<'de> de::Deserializer<'de> for ConstValue { } } + #[inline] fn deserialize_newtype_struct( self, _name: &'static str, @@ -181,6 +191,11 @@ impl<'de> de::Deserializer<'de> for ConstValue { visitor.visit_enum(EnumDeserializer { variant, value }) } + + #[inline] + fn is_human_readable(&self) -> bool { + false + } } struct EnumDeserializer { @@ -192,6 +207,7 @@ impl<'de> EnumAccess<'de> for EnumDeserializer { type Error = DeserializerError; type Variant = VariantDeserializer; + #[inline] fn variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), DeserializerError> where V: DeserializeSeed<'de>, @@ -217,6 +233,7 @@ struct VariantDeserializer { impl<'de> VariantAccess<'de> for VariantDeserializer { type Error = DeserializerError; + #[inline] fn unit_variant(self) -> Result<(), DeserializerError> { match self.value { Some(value) => Deserialize::deserialize(value), @@ -224,6 +241,7 @@ impl<'de> VariantAccess<'de> for VariantDeserializer { } } + #[inline] fn newtype_variant_seed(self, seed: T) -> Result where T: DeserializeSeed<'de>, @@ -337,6 +355,7 @@ impl<'de> SeqAccess<'de> for SeqDeserializer { } } + #[inline] fn size_hint(&self) -> Option { match self.iter.size_hint() { (lower, Some(upper)) if lower == upper => Some(upper), @@ -351,6 +370,7 @@ struct MapDeserializer { } impl MapDeserializer { + #[inline] fn new(map: BTreeMap) -> Self { MapDeserializer { iter: map.into_iter(), @@ -376,6 +396,7 @@ impl<'de> MapAccess<'de> for MapDeserializer { } } + #[inline] fn next_value_seed(&mut self, seed: T) -> Result where T: DeserializeSeed<'de>, @@ -386,6 +407,7 @@ impl<'de> MapAccess<'de> for MapDeserializer { } } + #[inline] fn size_hint(&self) -> Option { match self.iter.size_hint() { (lower, Some(upper)) if lower == upper => Some(upper), @@ -419,6 +441,7 @@ struct MapKeyDeserializer { impl<'de> serde::Deserializer<'de> for MapKeyDeserializer { type Error = DeserializerError; + #[inline] fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, @@ -426,6 +449,7 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer { NameDeserializer::new(self.key).deserialize_any(visitor) } + #[inline] fn deserialize_enum( self, name: &'static str, @@ -452,6 +476,7 @@ struct NameDeserializer { } impl NameDeserializer { + #[inline] fn new(value: Name) -> Self { NameDeserializer { value } } @@ -460,6 +485,7 @@ impl NameDeserializer { impl<'de> de::Deserializer<'de> for NameDeserializer { type Error = DeserializerError; + #[inline] fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, @@ -475,6 +501,7 @@ impl<'de> de::Deserializer<'de> for NameDeserializer { } /// Interpret a `ConstValue` as an instance of type `T`. +#[inline] pub fn from_value(value: ConstValue) -> Result { T::deserialize(value) } diff --git a/value/src/lib.rs b/value/src/lib.rs index 127ecd76..9c094149 100644 --- a/value/src/lib.rs +++ b/value/src/lib.rs @@ -3,9 +3,10 @@ #![warn(missing_docs)] #![forbid(unsafe_code)] -mod de; +mod deserializer; mod macros; -mod ser; +mod serializer; +mod value_serde; mod variables; use std::borrow::{Borrow, Cow}; @@ -16,12 +17,11 @@ use std::iter::FromIterator; use std::ops::Deref; use std::sync::Arc; -use serde::ser::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -pub use de::{from_value, DeserializerError}; -pub use ser::{to_value, SerializerError}; +pub use deserializer::{from_value, DeserializerError}; pub use serde_json::Number; +pub use serializer::{to_value, SerializerError}; pub use variables::Variables; @@ -121,8 +121,7 @@ impl<'de> Deserialize<'de> for Name { /// serialize `Upload` will fail, and `Enum` and `Upload` cannot be deserialized. /// /// [Reference](https://spec.graphql.org/June2018/#Value). -#[derive(Clone, Debug, Eq, Serialize, Deserialize)] -#[serde(untagged)] +#[derive(Clone, Debug, Eq)] pub enum ConstValue { /// `null`. Null, @@ -132,8 +131,9 @@ pub enum ConstValue { String(String), /// A boolean. Boolean(bool), + /// A binary. + Binary(Vec), /// An enum. These are typically in `SCREAMING_SNAKE_CASE`. - #[serde(skip_deserializing)] Enum(Name), /// A list of values. List(Vec), @@ -151,6 +151,7 @@ impl PartialEq for ConstValue { (ConstValue::Enum(a), ConstValue::String(b)) => a == b, (ConstValue::String(a), ConstValue::Enum(b)) => a == b, (ConstValue::Enum(a), ConstValue::Enum(b)) => a == b, + (ConstValue::Binary(a), ConstValue::Binary(b)) => a == b, (ConstValue::List(a), ConstValue::List(b)) => { if a.len() != b.len() { return false; @@ -267,6 +268,7 @@ impl ConstValue { Self::Number(num) => Value::Number(num), Self::String(s) => Value::String(s), Self::Boolean(b) => Value::Boolean(b), + Self::Binary(bytes) => Value::Binary(bytes), Self::Enum(v) => Value::Enum(v), Self::List(items) => { Value::List(items.into_iter().map(ConstValue::into_value).collect()) @@ -311,6 +313,7 @@ impl Display for ConstValue { Self::String(val) => write_quoted(val, f), Self::Boolean(true) => f.write_str("true"), Self::Boolean(false) => f.write_str("false"), + Self::Binary(bytes) => write_binary(bytes, f), Self::Null => f.write_str("null"), Self::Enum(name) => f.write_str(name), Self::List(items) => write_list(items, f), @@ -341,11 +344,9 @@ impl TryFrom for serde_json::Value { /// deserialized. /// /// [Reference](https://spec.graphql.org/June2018/#Value). -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Value { /// A variable, without the `$`. - #[serde(serialize_with = "fail_serialize_variable", skip_deserializing)] Variable(Name), /// `null`. Null, @@ -355,8 +356,9 @@ pub enum Value { String(String), /// A boolean. Boolean(bool), + /// A binary. + Binary(Vec), /// An enum. These are typically in `SCREAMING_SNAKE_CASE`. - #[serde(skip_deserializing)] Enum(Name), /// A list of values. List(Vec), @@ -383,6 +385,7 @@ impl Value { Self::Number(num) => ConstValue::Number(num), Self::String(s) => ConstValue::String(s), Self::Boolean(b) => ConstValue::Boolean(b), + Self::Binary(v) => ConstValue::Binary(v), Self::Enum(v) => ConstValue::Enum(v), Self::List(items) => ConstValue::List( items @@ -439,6 +442,7 @@ impl Display for Value { Self::String(val) => write_quoted(val, f), Self::Boolean(true) => f.write_str("true"), Self::Boolean(false) => f.write_str("false"), + Self::Binary(bytes) => write_binary(bytes, f), Self::Null => f.write_str("null"), Self::Enum(name) => f.write_str(name), Self::List(items) => write_list(items, f), @@ -466,10 +470,6 @@ impl TryFrom for serde_json::Value { } } -fn fail_serialize_variable(_: &str, _: S) -> Result { - Err(S::Error::custom("cannot serialize variable")) -} - fn write_quoted(s: &str, f: &mut Formatter<'_>) -> fmt::Result { f.write_char('"')?; for c in s.chars() { @@ -485,21 +485,45 @@ fn write_quoted(s: &str, f: &mut Formatter<'_>) -> fmt::Result { } f.write_char('"') } -fn write_list(list: impl IntoIterator, f: &mut Formatter<'_>) -> fmt::Result { + +fn write_binary(bytes: &[u8], f: &mut Formatter<'_>) -> fmt::Result { f.write_char('[')?; - for item in list { - item.fmt(f)?; + let mut iter = bytes.iter().copied(); + if let Some(value) = iter.next() { + value.fmt(f)?; + } + for value in iter { f.write_char(',')?; + value.fmt(f)?; } f.write_char(']') } + +fn write_list(list: impl IntoIterator, f: &mut Formatter<'_>) -> fmt::Result { + f.write_char('[')?; + let mut iter = list.into_iter(); + if let Some(item) = iter.next() { + item.fmt(f)?; + } + for item in iter { + f.write_char(',')?; + item.fmt(f)?; + } + f.write_char(']') +} + fn write_object( object: impl IntoIterator, f: &mut Formatter<'_>, ) -> fmt::Result { f.write_char('{')?; - for (name, value) in object { - write!(f, "{}: {},", name, value)?; + let mut iter = object.into_iter(); + if let Some((name, value)) = iter.next() { + write!(f, "{}: {}", name, value)?; + } + for (name, value) in iter { + f.write_char(',')?; + write!(f, "{}: {}", name, value)?; } f.write_char('}') } diff --git a/value/src/ser.rs b/value/src/serializer.rs similarity index 92% rename from value/src/ser.rs rename to value/src/serializer.rs index 383485f5..57e3706e 100644 --- a/value/src/ser.rs +++ b/value/src/serializer.rs @@ -32,6 +32,7 @@ impl ser::Error for SerializerError { } /// Convert a `T` into `ConstValue` which is an enum that can represent any valid GraphQL data. +#[inline] pub fn to_value(value: T) -> Result { value.serialize(Serializer) } @@ -49,46 +50,57 @@ impl ser::Serializer for Serializer { type SerializeStruct = SerializeStruct; type SerializeStructVariant = SerializeStructVariant; + #[inline] fn serialize_bool(self, v: bool) -> Result { Ok(ConstValue::Boolean(v)) } + #[inline] fn serialize_i8(self, v: i8) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_i16(self, v: i16) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_i32(self, v: i32) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_i64(self, v: i64) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_u8(self, v: u8) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_u16(self, v: u16) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_u32(self, v: u32) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_u64(self, v: u64) -> Result { Ok(ConstValue::Number(v.into())) } + #[inline] fn serialize_f32(self, v: f32) -> Result { self.serialize_f64(v as f64) } + #[inline] fn serialize_f64(self, v: f64) -> Result { match Number::from_f64(v) { Some(v) => Ok(ConstValue::Number(v)), @@ -96,22 +108,27 @@ impl ser::Serializer for Serializer { } } + #[inline] fn serialize_char(self, _v: char) -> Result { Err(SerializerError("char is not supported.".to_string())) } + #[inline] fn serialize_str(self, v: &str) -> Result { Ok(ConstValue::String(v.to_string())) } - fn serialize_bytes(self, _v: &[u8]) -> Result { - Err(SerializerError("bytes is not supported.".to_string())) + #[inline] + fn serialize_bytes(self, v: &[u8]) -> Result { + Ok(ConstValue::Binary(v.to_vec())) } + #[inline] fn serialize_none(self) -> Result { Ok(ConstValue::Null) } + #[inline] fn serialize_some(self, value: &T) -> Result where T: ser::Serialize, @@ -119,14 +136,17 @@ impl ser::Serializer for Serializer { value.serialize(self) } + #[inline] fn serialize_unit(self) -> Result { Ok(ConstValue::Null) } + #[inline] fn serialize_unit_struct(self, _name: &'static str) -> Result { Ok(ConstValue::Null) } + #[inline] fn serialize_unit_variant( self, _name: &'static str, @@ -136,6 +156,7 @@ impl ser::Serializer for Serializer { Ok(ConstValue::String(variant.to_string())) } + #[inline] fn serialize_newtype_struct( self, _name: &'static str, @@ -147,6 +168,7 @@ impl ser::Serializer for Serializer { value.serialize(self) } + #[inline] fn serialize_newtype_variant( self, _name: &'static str, @@ -164,14 +186,17 @@ impl ser::Serializer for Serializer { }) } + #[inline] fn serialize_seq(self, _len: Option) -> Result { Ok(SerializeSeq(vec![])) } + #[inline] fn serialize_tuple(self, _len: usize) -> Result { Ok(SerializeTuple(vec![])) } + #[inline] fn serialize_tuple_struct( self, _name: &'static str, @@ -180,6 +205,7 @@ impl ser::Serializer for Serializer { Ok(SerializeTupleStruct(vec![])) } + #[inline] fn serialize_tuple_variant( self, _name: &'static str, @@ -193,6 +219,7 @@ impl ser::Serializer for Serializer { )) } + #[inline] fn serialize_map(self, _len: Option) -> Result { Ok(SerializeMap { map: BTreeMap::new(), @@ -200,6 +227,7 @@ impl ser::Serializer for Serializer { }) } + #[inline] fn serialize_struct( self, _name: &'static str, @@ -208,6 +236,7 @@ impl ser::Serializer for Serializer { Ok(SerializeStruct(BTreeMap::new())) } + #[inline] fn serialize_struct_variant( self, _name: &'static str, @@ -217,6 +246,11 @@ impl ser::Serializer for Serializer { ) -> Result { Ok(SerializeStructVariant(Name::new(variant), BTreeMap::new())) } + + #[inline] + fn is_human_readable(&self) -> bool { + false + } } struct SerializeSeq(Vec); @@ -225,6 +259,7 @@ impl ser::SerializeSeq for SerializeSeq { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -234,6 +269,7 @@ impl ser::SerializeSeq for SerializeSeq { Ok(()) } + #[inline] fn end(self) -> Result { Ok(ConstValue::List(self.0)) } @@ -245,6 +281,7 @@ impl ser::SerializeTuple for SerializeTuple { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -254,6 +291,7 @@ impl ser::SerializeTuple for SerializeTuple { Ok(()) } + #[inline] fn end(self) -> Result { Ok(ConstValue::List(self.0)) } @@ -265,6 +303,7 @@ impl ser::SerializeTupleStruct for SerializeTupleStruct { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -274,6 +313,7 @@ impl ser::SerializeTupleStruct for SerializeTupleStruct { Ok(()) } + #[inline] fn end(self) -> Result { Ok(ConstValue::List(self.0)) } @@ -285,6 +325,7 @@ impl ser::SerializeTupleVariant for SerializeTupleVariant { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_field(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -294,6 +335,7 @@ impl ser::SerializeTupleVariant for SerializeTupleVariant { Ok(()) } + #[inline] fn end(self) -> Result { let mut map = BTreeMap::new(); map.insert(self.0, ConstValue::List(self.1)); @@ -310,6 +352,7 @@ impl ser::SerializeMap for SerializeMap { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_key(&mut self, key: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -319,6 +362,7 @@ impl ser::SerializeMap for SerializeMap { Ok(()) } + #[inline] fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: ser::Serialize, @@ -328,6 +372,7 @@ impl ser::SerializeMap for SerializeMap { Ok(()) } + #[inline] fn end(self) -> Result { Ok(ConstValue::Object(self.map)) } @@ -339,6 +384,7 @@ impl ser::SerializeStruct for SerializeStruct { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_field( &mut self, key: &'static str, @@ -353,6 +399,7 @@ impl ser::SerializeStruct for SerializeStruct { Ok(()) } + #[inline] fn end(self) -> Result { Ok(ConstValue::Object(self.0)) } @@ -364,6 +411,7 @@ impl ser::SerializeStructVariant for SerializeStructVariant { type Ok = ConstValue; type Error = SerializerError; + #[inline] fn serialize_field( &mut self, key: &'static str, @@ -378,6 +426,7 @@ impl ser::SerializeStructVariant for SerializeStructVariant { Ok(()) } + #[inline] fn end(self) -> Result { let mut map = BTreeMap::new(); map.insert(self.0, ConstValue::Object(self.1)); @@ -385,6 +434,7 @@ impl ser::SerializeStructVariant for SerializeStructVariant { } } +#[inline] fn key_must_be_a_string() -> SerializerError { SerializerError("Key must be a string".to_string()) } @@ -402,66 +452,82 @@ impl serde::Serializer for MapKeySerializer { type SerializeStruct = Impossible; type SerializeStructVariant = Impossible; + #[inline] fn serialize_bool(self, _v: bool) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_i8(self, _v: i8) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_i16(self, _v: i16) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_i32(self, _v: i32) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_i64(self, _v: i64) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_u8(self, _v: u8) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_u16(self, _v: u16) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_u32(self, _v: u32) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_u64(self, _v: u64) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_f32(self, _v: f32) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_f64(self, _v: f64) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_char(self, _v: char) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_str(self, v: &str) -> Result { Ok(Name::new(v)) } + #[inline] fn serialize_bytes(self, _v: &[u8]) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_none(self) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_some(self, _value: &T) -> Result where T: Serialize, @@ -469,14 +535,17 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_unit(self) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_unit_struct(self, _name: &'static str) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_unit_variant( self, _name: &'static str, @@ -486,6 +555,7 @@ impl serde::Serializer for MapKeySerializer { Ok(Name::new(variant)) } + #[inline] fn serialize_newtype_struct( self, _name: &'static str, @@ -497,6 +567,7 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_newtype_variant( self, _name: &'static str, @@ -510,14 +581,17 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_seq(self, _len: Option) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_tuple(self, _len: usize) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_tuple_struct( self, _name: &'static str, @@ -526,6 +600,7 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_tuple_variant( self, _name: &'static str, @@ -536,10 +611,12 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_map(self, _len: Option) -> Result { Err(key_must_be_a_string()) } + #[inline] fn serialize_struct( self, _name: &'static str, @@ -548,6 +625,7 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } + #[inline] fn serialize_struct_variant( self, _name: &'static str, diff --git a/value/src/value_serde.rs b/value/src/value_serde.rs new file mode 100644 index 00000000..6011e204 --- /dev/null +++ b/value/src/value_serde.rs @@ -0,0 +1,293 @@ +use std::collections::BTreeMap; +use std::fmt::{self, Formatter}; + +use serde::de::{Error as DeError, MapAccess, SeqAccess, Visitor}; +use serde::ser::Error as SerError; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +use crate::{ConstValue, Number, Value}; + +impl Serialize for ConstValue { + fn serialize(&self, serializer: S) -> Result { + match self { + ConstValue::Null => serializer.serialize_none(), + ConstValue::Number(v) => v.serialize(serializer), + ConstValue::String(v) => serializer.serialize_str(v), + ConstValue::Boolean(v) => serializer.serialize_bool(*v), + ConstValue::Binary(v) => serializer.serialize_bytes(v), + ConstValue::Enum(v) => serializer.serialize_str(v), + ConstValue::List(v) => v.serialize(serializer), + ConstValue::Object(v) => v.serialize(serializer), + } + } +} + +impl<'de> Deserialize<'de> for ConstValue { + fn deserialize>(deserializer: D) -> Result { + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = ConstValue; + + #[inline] + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("any valid value") + } + + #[inline] + fn visit_bool(self, v: bool) -> Result + where + E: DeError, + { + Ok(ConstValue::Boolean(v)) + } + + #[inline] + fn visit_i64(self, v: i64) -> Result + where + E: DeError, + { + Ok(ConstValue::Number(v.into())) + } + + #[inline] + fn visit_u64(self, v: u64) -> Result + where + E: DeError, + { + Ok(ConstValue::Number(v.into())) + } + + #[inline] + fn visit_f64(self, v: f64) -> Result + where + E: DeError, + { + Ok(Number::from_f64(v).map_or(ConstValue::Null, ConstValue::Number)) + } + + #[inline] + fn visit_str(self, v: &str) -> Result + where + E: DeError, + { + Ok(ConstValue::String(v.to_string())) + } + + #[inline] + fn visit_string(self, v: String) -> Result + where + E: DeError, + { + Ok(ConstValue::String(v)) + } + + #[inline] + fn visit_bytes(self, v: &[u8]) -> Result + where + E: DeError, + { + Ok(ConstValue::Binary(v.to_vec())) + } + + #[inline] + fn visit_byte_buf(self, v: Vec) -> Result + where + E: DeError, + { + Ok(ConstValue::Binary(v)) + } + + #[inline] + fn visit_none(self) -> Result + where + E: DeError, + { + Ok(ConstValue::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result + where + E: DeError, + { + Ok(ConstValue::Null) + } + + fn visit_seq(self, mut visitor: A) -> Result + where + A: SeqAccess<'de>, + { + let mut vec = Vec::new(); + while let Some(elem) = visitor.next_element()? { + vec.push(elem); + } + Ok(ConstValue::List(vec)) + } + + fn visit_map(self, mut visitor: A) -> Result + where + A: MapAccess<'de>, + { + let mut map = BTreeMap::new(); + while let Some((name, value)) = visitor.next_entry()? { + map.insert(name, value); + } + Ok(ConstValue::Object(map)) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl Serialize for Value { + fn serialize(&self, serializer: S) -> Result { + match self { + Value::Variable(_) => Err(S::Error::custom("cannot serialize variable")), + Value::Null => serializer.serialize_none(), + Value::Number(v) => v.serialize(serializer), + Value::String(v) => serializer.serialize_str(v), + Value::Boolean(v) => serializer.serialize_bool(*v), + Value::Binary(v) => serializer.serialize_bytes(v), + Value::Enum(v) => serializer.serialize_str(v), + Value::List(v) => v.serialize(serializer), + Value::Object(v) => v.serialize(serializer), + } + } +} + +impl<'de> Deserialize<'de> for Value { + fn deserialize>(deserializer: D) -> Result { + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = Value; + + #[inline] + fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { + formatter.write_str("any valid value") + } + + #[inline] + fn visit_bool(self, v: bool) -> Result + where + E: DeError, + { + Ok(Value::Boolean(v)) + } + + #[inline] + fn visit_i64(self, v: i64) -> Result + where + E: DeError, + { + Ok(Value::Number(v.into())) + } + + #[inline] + fn visit_u64(self, v: u64) -> Result + where + E: DeError, + { + Ok(Value::Number(v.into())) + } + + #[inline] + fn visit_f64(self, v: f64) -> Result + where + E: DeError, + { + Ok(Number::from_f64(v).map_or(Value::Null, Value::Number)) + } + + #[inline] + fn visit_str(self, v: &str) -> Result + where + E: DeError, + { + Ok(Value::String(v.to_string())) + } + + #[inline] + fn visit_string(self, v: String) -> Result + where + E: DeError, + { + Ok(Value::String(v)) + } + + #[inline] + fn visit_bytes(self, v: &[u8]) -> Result + where + E: DeError, + { + Ok(Value::Binary(v.to_vec())) + } + + #[inline] + fn visit_byte_buf(self, v: Vec) -> Result + where + E: DeError, + { + Ok(Value::Binary(v)) + } + + #[inline] + fn visit_none(self) -> Result + where + E: DeError, + { + Ok(Value::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result + where + E: DeError, + { + Ok(Value::Null) + } + + fn visit_seq(self, mut visitor: A) -> Result + where + A: SeqAccess<'de>, + { + let mut vec = Vec::new(); + while let Some(elem) = visitor.next_element()? { + vec.push(elem); + } + Ok(Value::List(vec)) + } + + fn visit_map(self, mut visitor: A) -> Result + where + A: MapAccess<'de>, + { + let mut map = BTreeMap::new(); + while let Some((name, value)) = visitor.next_entry()? { + map.insert(name, value); + } + Ok(Value::Object(map)) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} diff --git a/value/tests/test_serde.rs b/value/tests/test_serde.rs index b27d7ac7..916a0e80 100644 --- a/value/tests/test_serde.rs +++ b/value/tests/test_serde.rs @@ -19,6 +19,7 @@ fn test_serde() { test_value(Some(100i32)); test_value(ConstValue::Null); test_value(vec![0i32, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + test_value(b"123456".to_vec()); #[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)] struct NewType(i32); @@ -52,3 +53,11 @@ fn test_serde() { b: Some(Enum::B), }); } + +#[test] +fn test_binary() { + assert_eq!( + to_value(Value::Binary(b"123456".to_vec())).unwrap(), + ConstValue::Binary(b"123456".to_vec()) + ); +}