aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2018-05-24 07:25:15 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-05-24 07:25:42 -0700
commitb192b562b49e0de2ff9cbc20a3dd995ad615f78d (patch)
treef3532b3553bfaa7c307f927d899fa5cb8c2037c1
parenteddcac68781e43905b1e00f1b687bfa1134c2327 (diff)
downloadmilf-rs-b192b562b49e0de2ff9cbc20a3dd995ad615f78d.tar.gz
milf-rs-b192b562b49e0de2ff9cbc20a3dd995ad615f78d.zip
Support fixed-length arrays
Turns out these are deserialized/serialized as tuples! While we're at it add support for tuple variants and tuple structs through the same paths. Closes #244
-rw-r--r--src/ser.rs117
-rw-r--r--test-suite/tests/serde.rs15
2 files changed, 116 insertions, 16 deletions
diff --git a/src/ser.rs b/src/ser.rs
index b8cec35..8f4e72b 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -741,9 +741,9 @@ impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = SerializeSeq<'a, 'b>;
- type SerializeTuple = ser::Impossible<(), Error>;
- type SerializeTupleStruct = ser::Impossible<(), Error>;
- type SerializeTupleVariant = ser::Impossible<(), Error>;
+ type SerializeTuple = SerializeSeq<'a, 'b>;
+ type SerializeTupleStruct = SerializeSeq<'a, 'b>;
+ type SerializeTupleVariant = SerializeSeq<'a, 'b>;
type SerializeMap = SerializeTable<'a, 'b>;
type SerializeStruct = SerializeTable<'a, 'b>;
type SerializeStructVariant = ser::Impossible<(), Error>;
@@ -892,23 +892,23 @@ impl<'a, 'b> ser::Serializer for &'b mut Serializer<'a> {
})
}
- fn serialize_tuple(self, _len: usize)
+ fn serialize_tuple(self, len: usize)
-> Result<Self::SerializeTuple, Self::Error> {
- Err(Error::UnsupportedType)
+ self.serialize_seq(Some(len))
}
- fn serialize_tuple_struct(self, _name: &'static str, _len: usize)
+ fn serialize_tuple_struct(self, _name: &'static str, len: usize)
-> Result<Self::SerializeTupleStruct, Self::Error> {
- Err(Error::UnsupportedType)
+ self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
- _len: usize)
+ len: usize)
-> Result<Self::SerializeTupleVariant, Self::Error> {
- Err(Error::UnsupportedType)
+ self.serialize_seq(Some(len))
}
fn serialize_map(self, _len: Option<usize>)
@@ -998,6 +998,51 @@ impl<'a, 'b> ser::SerializeSeq for SerializeSeq<'a, 'b> {
}
}
+impl<'a, 'b> ser::SerializeTuple for SerializeSeq<'a, 'b> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where T: ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<(), Error> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl<'a, 'b> ser::SerializeTupleVariant for SerializeSeq<'a, 'b> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where T: ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<(), Error> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl<'a, 'b> ser::SerializeTupleStruct for SerializeSeq<'a, 'b> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where T: ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<(), Error> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
impl<'a, 'b> ser::SerializeMap for SerializeTable<'a, 'b> {
type Ok = ();
type Error = Error;
@@ -1543,9 +1588,9 @@ impl<E: ser::Error> ser::Serializer for Categorize<E> {
type Ok = Category;
type Error = E;
type SerializeSeq = Self;
- type SerializeTuple = ser::Impossible<Category, E>;
- type SerializeTupleStruct = ser::Impossible<Category, E>;
- type SerializeTupleVariant = ser::Impossible<Category, E>;
+ type SerializeTuple = Self;
+ type SerializeTupleStruct = Self;
+ type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = ser::Impossible<Category, E>;
@@ -1639,15 +1684,15 @@ impl<E: ser::Error> ser::Serializer for Categorize<E> {
}
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
- Err(ser::Error::custom("unsupported"))
+ Ok(self)
}
fn serialize_tuple_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
- Err(ser::Error::custom("unsupported"))
+ Ok(self)
}
fn serialize_tuple_variant(self, _: &'static str, _: u32, _: &'static str, _: usize) -> Result<Self::SerializeTupleVariant, Self::Error> {
- Err(ser::Error::custom("unsupported"))
+ Ok(self)
}
fn serialize_map(self, _: Option<usize>) -> Result<Self, Self::Error> {
@@ -1677,6 +1722,48 @@ impl<E: ser::Error> ser::SerializeSeq for Categorize<E> {
}
}
+impl<E: ser::Error> ser::SerializeTuple for Categorize<E> {
+ type Ok = Category;
+ type Error = E;
+
+ fn serialize_element<T: ?Sized + ser::Serialize>(&mut self, _: &T)
+ -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ Ok(Category::Array)
+ }
+}
+
+impl<E: ser::Error> ser::SerializeTupleVariant for Categorize<E> {
+ type Ok = Category;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, _: &T)
+ -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ Ok(Category::Array)
+ }
+}
+
+impl<E: ser::Error> ser::SerializeTupleStruct for Categorize<E> {
+ type Ok = Category;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, _: &T)
+ -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ Ok(Category::Array)
+ }
+}
+
impl<E: ser::Error> ser::SerializeMap for Categorize<E> {
type Ok = Category;
type Error = E;
diff --git a/test-suite/tests/serde.rs b/test-suite/tests/serde.rs
index 57fa5db..446cd7a 100644
--- a/test-suite/tests/serde.rs
+++ b/test-suite/tests/serde.rs
@@ -569,10 +569,23 @@ fn table_structs_empty() {
expected.insert("bar".to_string(), CanBeEmpty::default());
expected.insert("baz".to_string(), CanBeEmpty::default());
expected.insert(
- "bazv".to_string(),
+ "bazv".to_string(),
CanBeEmpty {a: Some("foo".to_string()), b: None},
);
expected.insert("foo".to_string(), CanBeEmpty::default());
assert_eq!(value, expected);
assert_eq!(toml::to_string(&value).unwrap(), text);
}
+
+#[test]
+fn fixed_size_array() {
+ #[derive(Serialize, PartialEq, Eq, Deserialize, Debug)]
+ struct Entity {
+ pos: [i32; 2]
+ }
+ let text = "pos = [1, 2]\n";
+ let value: Entity = toml::from_str(text).unwrap();
+ let expected = Entity { pos: [1, 2] };
+ assert_eq!(value, expected);
+ assert_eq!(toml::to_string(&value).unwrap(), text);
+}