From d083e58357e27b9850b702c1aa41990896bf732b Mon Sep 17 00:00:00 2001 From: James Kay Date: Thu, 5 Sep 2019 15:18:26 +0100 Subject: [PATCH] Nested dotted-table enums (#329) Add support for deserializing enums from nested dotted tables. --- src/de.rs | 33 +++++++++++++++++++++++++++++- tests/enum_external_deserialize.rs | 20 ++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/de.rs b/src/de.rs index 540600f..03372c6 100644 --- a/src/de.rs +++ b/src/de.rs @@ -541,10 +541,41 @@ impl<'de, 'b> de::Deserializer<'de> for MapVisitor<'de, 'b> { visitor.visit_newtype_struct(self) } + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + if self.tables.len() != 1 { + return Err(Error::custom( + Some(self.cur), + "enum table must contain exactly one table".into(), + )); + } + let table = &mut self.tables[0]; + let values = table.values.take().expect("table has no values?"); + if table.header.len() == 0 { + return Err(self.de.error(self.cur, ErrorKind::EmptyTableKey)); + } + let name = table.header[table.header.len() - 1].to_owned(); + visitor.visit_enum(DottedTableDeserializer { + name: name, + value: Value { + e: E::DottedTable(values), + start: 0, + end: 0, + }, + }) + } + serde::forward_to_deserialize_any! { bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq bytes byte_buf map struct unit identifier - ignored_any unit_struct tuple_struct tuple enum + ignored_any unit_struct tuple_struct tuple } } diff --git a/tests/enum_external_deserialize.rs b/tests/enum_external_deserialize.rs index 3c38580..6d45b48 100644 --- a/tests/enum_external_deserialize.rs +++ b/tests/enum_external_deserialize.rs @@ -2,6 +2,11 @@ extern crate serde_derive; extern crate toml; +#[derive(Debug, Deserialize, PartialEq)] +struct OuterStruct { + inner: TheEnum, +} + #[derive(Debug, Deserialize, PartialEq)] enum TheEnum { Plain, @@ -181,6 +186,21 @@ mod enum_struct { .unwrap() ); } + + #[test] + fn from_nested_dotted_table() { + assert_eq!( + OuterStruct { + inner: TheEnum::Struct { value: -123 } + }, + toml::from_str( + r#"[inner.Struct] + value = -123 + "# + ) + .unwrap() + ); + } } mod enum_array {