parent
9a69c17a4e
commit
4f28c2f639
|
@ -11,7 +11,8 @@ extern crate serde_derive;
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
plain: MyEnum,
|
plain: MyEnum,
|
||||||
// tuple: MyEnum,
|
plain_table: MyEnum,
|
||||||
|
tuple: MyEnum,
|
||||||
#[serde(rename = "struct")]
|
#[serde(rename = "struct")]
|
||||||
structv: MyEnum,
|
structv: MyEnum,
|
||||||
newtype: MyEnum,
|
newtype: MyEnum,
|
||||||
|
@ -29,12 +30,13 @@ enum MyEnum {
|
||||||
fn main() {
|
fn main() {
|
||||||
let toml_str = r#"
|
let toml_str = r#"
|
||||||
plain = "Plain"
|
plain = "Plain"
|
||||||
# tuple = { 0 = 123, 1 = true }
|
plain_table = { Plain = {} }
|
||||||
|
tuple = { Tuple = { 0 = 123, 1 = true } }
|
||||||
struct = { Struct = { value = 123 } }
|
struct = { Struct = { value = 123 } }
|
||||||
newtype = { NewType = "value" }
|
newtype = { NewType = "value" }
|
||||||
my_enum = [
|
my_enum = [
|
||||||
{ Plain = {} },
|
{ Plain = {} },
|
||||||
# { Tuple = { 0 = 123, 1 = true } },
|
{ Tuple = { 0 = 123, 1 = true } },
|
||||||
{ NewType = "value" },
|
{ NewType = "value" },
|
||||||
{ Struct = { value = 123 } }
|
{ Struct = { value = 123 } }
|
||||||
]"#;
|
]"#;
|
||||||
|
|
65
src/de.rs
65
src/de.rs
|
@ -162,6 +162,12 @@ enum ErrorKind {
|
||||||
/// A struct was expected but something else was found
|
/// A struct was expected but something else was found
|
||||||
ExpectedString,
|
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.
|
/// Dotted key attempted to extend something that is not a table.
|
||||||
DottedKeyInvalidType,
|
DottedKeyInvalidType,
|
||||||
|
|
||||||
|
@ -757,7 +763,7 @@ impl<'de> de::EnumAccess<'de> for InlineTableDeserializer<'de> {
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::from_kind(ErrorKind::Wanted {
|
return Err(Error::from_kind(ErrorKind::Wanted {
|
||||||
expected: "table with exactly 1 entry",
|
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;
|
type Error = Error;
|
||||||
|
|
||||||
fn unit_variant(self) -> Result<(), Self::Error> {
|
fn unit_variant(self) -> Result<(), Self::Error> {
|
||||||
// TODO: Error handling if there are entries
|
match self.next_value.expect("Expected value").e {
|
||||||
|
E::InlineTable(values) | E::DottedTable(values) => {
|
||||||
|
if values.len() == 0 {
|
||||||
Ok(())
|
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>
|
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
|
||||||
|
@ -785,12 +802,46 @@ 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
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
|
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!()
|
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>(
|
fn struct_variant<V>(
|
||||||
self,
|
self,
|
||||||
|
@ -1470,7 +1521,11 @@ impl fmt::Display for Error {
|
||||||
ErrorKind::MultilineStringKey => "multiline strings are not allowed for key".fmt(f)?,
|
ErrorKind::MultilineStringKey => "multiline strings are not allowed for key".fmt(f)?,
|
||||||
ErrorKind::Custom => self.inner.message.fmt(f)?,
|
ErrorKind::Custom => self.inner.message.fmt(f)?,
|
||||||
ErrorKind::ExpectedString => "expected string".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!(),
|
ErrorKind::__Nonexhaustive => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1515,6 +1570,8 @@ impl error::Error for Error {
|
||||||
ErrorKind::MultilineStringKey => "invalid multiline string for key",
|
ErrorKind::MultilineStringKey => "invalid multiline string for key",
|
||||||
ErrorKind::Custom => "a custom error",
|
ErrorKind::Custom => "a custom error",
|
||||||
ErrorKind::ExpectedString => "expected string",
|
ErrorKind::ExpectedString => "expected string",
|
||||||
|
ErrorKind::ExpectedTuple(_) => "expected tuple",
|
||||||
|
ErrorKind::ExpectedEmptyTable => "expected empty table",
|
||||||
ErrorKind::DottedKeyInvalidType => "dotted key invalid type",
|
ErrorKind::DottedKeyInvalidType => "dotted key invalid type",
|
||||||
ErrorKind::__Nonexhaustive => panic!(),
|
ErrorKind::__Nonexhaustive => panic!(),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue