aboutsummaryrefslogtreecommitdiff
path: root/src/value.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/value.rs')
-rw-r--r--src/value.rs126
1 files changed, 104 insertions, 22 deletions
diff --git a/src/value.rs b/src/value.rs
index 2785d9d..e6f832a 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -770,6 +770,13 @@ impl<'de> serde::de::VariantAccess<'de> for MapEnumDeserializer {
fn unit_variant(self) -> Result<(), Self::Error> {
use de::Error;
match self.value {
+ Value::Array(values) => {
+ if values.is_empty() {
+ Ok(())
+ } else {
+ Err(Error::custom("expected empty array"))
+ }
+ }
Value::Table(values) => {
if values.is_empty() {
Ok(())
@@ -797,8 +804,15 @@ impl<'de> serde::de::VariantAccess<'de> for MapEnumDeserializer {
{
use de::Error;
match self.value {
+ Value::Array(values) => {
+ if values.len() == len {
+ serde::de::Deserializer::deserialize_seq(values.into_deserializer(), visitor)
+ } else {
+ Err(Error::custom(format!("expected tuple with length {}", len)))
+ }
+ }
Value::Table(values) => {
- let tuple_values = values
+ let tuple_values: Result<Vec<_>, _> = values
.into_iter()
.enumerate()
.map(|(index, (key, value))| match key.parse::<usize>() {
@@ -808,17 +822,8 @@ impl<'de> serde::de::VariantAccess<'de> for MapEnumDeserializer {
index, key
))),
})
- // Fold all values into a `Vec`, or return the first error.
- .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
- result.and_then(move |mut tuple_values| match value_result {
- Ok(value) => {
- tuple_values.push(value);
- Ok(tuple_values)
- }
- // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
- Err(e) => Err(e),
- })
- })?;
+ .collect();
+ let tuple_values = tuple_values?;
if tuple_values.len() == len {
serde::de::Deserializer::deserialize_seq(
@@ -870,10 +875,10 @@ impl ser::Serializer for ValueSerializer {
type SerializeSeq = ValueSerializeVec;
type SerializeTuple = ValueSerializeVec;
type SerializeTupleStruct = ValueSerializeVec;
- type SerializeTupleVariant = ValueSerializeVec;
+ type SerializeTupleVariant = ValueSerializeTupleVariant;
type SerializeMap = ValueSerializeMap;
type SerializeStruct = ValueSerializeMap;
- type SerializeStructVariant = ser::Impossible<Value, crate::ser::Error>;
+ type SerializeStructVariant = ValueSerializeStructVariant;
fn serialize_bool(self, value: bool) -> Result<Value, crate::ser::Error> {
Ok(Value::Boolean(value))
@@ -916,10 +921,14 @@ impl ser::Serializer for ValueSerializer {
}
fn serialize_f32(self, value: f32) -> Result<Value, crate::ser::Error> {
- self.serialize_f64(value.into())
+ self.serialize_f64(value as f64)
}
- fn serialize_f64(self, value: f64) -> Result<Value, crate::ser::Error> {
+ fn serialize_f64(self, mut value: f64) -> Result<Value, crate::ser::Error> {
+ // Discard sign of NaN. See ValueSerializer::serialize_f64.
+ if value.is_nan() {
+ value = value.copysign(1.0);
+ }
Ok(Value::Float(value))
}
@@ -1015,10 +1024,10 @@ impl ser::Serializer for ValueSerializer {
self,
_name: &'static str,
_variant_index: u32,
- _variant: &'static str,
+ variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, crate::ser::Error> {
- self.serialize_seq(Some(len))
+ Ok(ValueSerializeTupleVariant::tuple(variant, len))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> {
@@ -1040,12 +1049,12 @@ impl ser::Serializer for ValueSerializer {
fn serialize_struct_variant(
self,
- name: &'static str,
+ _name: &'static str,
_variant_index: u32,
- _variant: &'static str,
- _len: usize,
+ variant: &'static str,
+ len: usize,
) -> Result<Self::SerializeStructVariant, crate::ser::Error> {
- Err(crate::ser::Error::unsupported_type(Some(name)))
+ Ok(ValueSerializeStructVariant::struct_(variant, len))
}
}
@@ -1453,3 +1462,76 @@ impl<'a, 'de> de::Visitor<'de> for DatetimeOrTable<'a> {
}
}
}
+
+type ValueSerializeTupleVariant = ValueSerializeVariant<ValueSerializeVec>;
+type ValueSerializeStructVariant = ValueSerializeVariant<ValueSerializeMap>;
+
+struct ValueSerializeVariant<T> {
+ variant: &'static str,
+ inner: T,
+}
+
+impl ValueSerializeVariant<ValueSerializeVec> {
+ pub(crate) fn tuple(variant: &'static str, len: usize) -> Self {
+ Self {
+ variant,
+ inner: ValueSerializeVec {
+ vec: Vec::with_capacity(len),
+ },
+ }
+ }
+}
+
+impl ValueSerializeVariant<ValueSerializeMap> {
+ pub(crate) fn struct_(variant: &'static str, len: usize) -> Self {
+ Self {
+ variant,
+ inner: ValueSerializeMap {
+ ser: SerializeMap {
+ map: Table::with_capacity(len),
+ next_key: None,
+ },
+ },
+ }
+ }
+}
+
+impl serde::ser::SerializeTupleVariant for ValueSerializeVariant<ValueSerializeVec> {
+ type Ok = crate::Value;
+ type Error = crate::ser::Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(&mut self.inner, value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ let inner = serde::ser::SerializeSeq::end(self.inner)?;
+ let mut table = Table::new();
+ table.insert(self.variant.to_owned(), inner);
+ Ok(Value::Table(table))
+ }
+}
+
+impl serde::ser::SerializeStructVariant for ValueSerializeVariant<ValueSerializeMap> {
+ type Ok = crate::Value;
+ type Error = crate::ser::Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize + ?Sized,
+ {
+ serde::ser::SerializeStruct::serialize_field(&mut self.inner, key, value)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ let inner = serde::ser::SerializeStruct::end(self.inner)?;
+ let mut table = Table::new();
+ table.insert(self.variant.to_owned(), inner);
+ Ok(Value::Table(table))
+ }
+}