aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzriel Hoh <azriel91@gmail.com>2018-10-10 11:36:46 +1300
committerAzriel Hoh <azriel91@gmail.com>2018-11-10 11:07:23 +1300
commit9ce37a6b0278d4c422e5cac7003cf908cc2c9e3f (patch)
tree1ac8b4f500df6ff995668b9075d1c25ee39a3fdc
parentb6559e9e8dbbe2d9dacc1b5960541315a9765816 (diff)
downloadmilf-rs-9ce37a6b0278d4c422e5cac7003cf908cc2c9e3f.tar.gz
milf-rs-9ce37a6b0278d4c422e5cac7003cf908cc2c9e3f.zip
Implemented enum tuple deserialization.
Issue #225
-rw-r--r--examples/enum_external.rs8
-rw-r--r--src/de.rs69
2 files changed, 68 insertions, 9 deletions
diff --git a/examples/enum_external.rs b/examples/enum_external.rs
index 095dca5..e2ac4f8 100644
--- a/examples/enum_external.rs
+++ b/examples/enum_external.rs
@@ -11,7 +11,8 @@ extern crate serde_derive;
#[derive(Debug, Deserialize)]
struct Config {
plain: MyEnum,
- // tuple: MyEnum,
+ plain_table: MyEnum,
+ tuple: MyEnum,
#[serde(rename = "struct")]
structv: MyEnum,
newtype: MyEnum,
@@ -29,12 +30,13 @@ enum MyEnum {
fn main() {
let toml_str = r#"
plain = "Plain"
- # tuple = { 0 = 123, 1 = true }
+ plain_table = { Plain = {} }
+ tuple = { Tuple = { 0 = 123, 1 = true } }
struct = { Struct = { value = 123 } }
newtype = { NewType = "value" }
my_enum = [
{ Plain = {} },
- # { Tuple = { 0 = 123, 1 = true } },
+ { Tuple = { 0 = 123, 1 = true } },
{ NewType = "value" },
{ Struct = { value = 123 } }
]"#;
diff --git a/src/de.rs b/src/de.rs
index 5de4f6a..4f5a5f2 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -162,6 +162,12 @@ enum ErrorKind {
/// A struct was expected but something else was found
ExpectedString,
+ /// A tuple with a certain number of elements was expected but something else was found
+ ExpectedTuple(usize),
+
+ /// An empty table was expected but entries were found
+ ExpectedEmptyTable,
+
/// Dotted key attempted to extend something that is not a table.
DottedKeyInvalidType,
@@ -757,7 +763,7 @@ impl<'de> de::EnumAccess<'de> for InlineTableDeserializer<'de> {
None => {
return Err(Error::from_kind(ErrorKind::Wanted {
expected: "table with exactly 1 entry",
- found: "empty map",
+ found: "empty table",
}))
}
};
@@ -772,8 +778,19 @@ impl<'de> de::VariantAccess<'de> for InlineTableDeserializer<'de> {
type Error = Error;
fn unit_variant(self) -> Result<(), Self::Error> {
- // TODO: Error handling if there are entries
- Ok(())
+ match self.next_value.expect("Expected value").e {
+ E::InlineTable(values) | E::DottedTable(values) => {
+ if values.len() == 0 {
+ Ok(())
+ } else {
+ Err(Error::from_kind(ErrorKind::ExpectedEmptyTable))
+ }
+ }
+ e @ _ => Err(Error::from_kind(ErrorKind::Wanted {
+ expected: "table",
+ found: e.type_name(),
+ })),
+ }
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
@@ -785,11 +802,45 @@ impl<'de> de::VariantAccess<'de> for InlineTableDeserializer<'de> {
))
}
- fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
+ fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
- unimplemented!()
+ let next_value = self.next_value.expect("Expected value");
+ match next_value.e {
+ E::InlineTable(values) | E::DottedTable(values) => {
+ let tuple_values = values
+ .into_iter()
+ .enumerate()
+ .filter_map(|(index, (key, value))| {
+ // TODO: Is this expensive?
+ if key == format!("{}", index) {
+ Some(value)
+ } else {
+ // TODO: Err()
+ unimplemented!()
+ }
+ })
+ .collect::<Vec<_>>(); // TODO: is this expensive?
+
+ if tuple_values.len() == len {
+ de::Deserializer::deserialize_seq(
+ ValueDeserializer::new(Value {
+ e: E::Array(tuple_values),
+ start: next_value.start,
+ end: next_value.end,
+ }),
+ visitor,
+ )
+ } else {
+ Err(Error::from_kind(ErrorKind::ExpectedTuple(len)))
+ }
+ }
+ e @ _ => Err(Error::from_kind(ErrorKind::Wanted {
+ expected: "table",
+ found: e.type_name(),
+ })),
+ }
}
fn struct_variant<V>(
@@ -1470,7 +1521,11 @@ impl fmt::Display for Error {
ErrorKind::MultilineStringKey => "multiline strings are not allowed for key".fmt(f)?,
ErrorKind::Custom => self.inner.message.fmt(f)?,
ErrorKind::ExpectedString => "expected string".fmt(f)?,
- ErrorKind::DottedKeyInvalidType => "dotted key attempted to extend non-table type".fmt(f)?,
+ ErrorKind::ExpectedTuple(l) => write!(f, "expected tuple with length {}", l)?,
+ ErrorKind::ExpectedEmptyTable => "expected empty table".fmt(f)?,
+ ErrorKind::DottedKeyInvalidType => {
+ "dotted key attempted to extend non-table type".fmt(f)?
+ }
ErrorKind::__Nonexhaustive => panic!(),
}
@@ -1515,6 +1570,8 @@ impl error::Error for Error {
ErrorKind::MultilineStringKey => "invalid multiline string for key",
ErrorKind::Custom => "a custom error",
ErrorKind::ExpectedString => "expected string",
+ ErrorKind::ExpectedTuple(_) => "expected tuple",
+ ErrorKind::ExpectedEmptyTable => "expected empty table",
ErrorKind::DottedKeyInvalidType => "dotted key invalid type",
ErrorKind::__Nonexhaustive => panic!(),
}