From 935b004c8e51165b5cdefcaf194cc8ec48cb65e4 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 17 Nov 2020 21:03:33 +0000 Subject: [PATCH] wip toml, doex not work, progressing Signed-off-by: Ian Jackson --- src/toml.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 9 deletions(-) diff --git a/src/toml.rs b/src/toml.rs index 8ddc8254..ffe4efbc 100644 --- a/src/toml.rs +++ b/src/toml.rs @@ -7,11 +7,17 @@ use std::iter::Peekable; use std::slice; use fehler::throws; -use serde::forward_to_deserialize_any; -use serde::de::{Deserialize, DeserializeOwned, Deserializer, DeserializeSeed}; -use serde::de::{IntoDeserializer, MapAccess, SeqAccess, Visitor}; +use if_chain::if_chain; use thiserror::Error; +use serde::forward_to_deserialize_any; +use serde::de::{ + Deserialize, DeserializeOwned, Deserializer, + DeserializeSeed, EnumAccess, + IntoDeserializer, MapAccess, + SeqAccess, VariantAccess, Visitor +}; + #[derive(Error,Debug)] pub enum Error { #[error("deserialize failed (improper TOML structure?): {0}")] @@ -26,6 +32,14 @@ impl serde::de::Error for Error { } } +fn str_deserialize<'de, S: DeserializeSeed<'de>> + (seed: S, k: &'de str) -> Result +{ + seed.deserialize( + k.into_deserializer() + ) +} + pub struct TomlDe<'de>(pub &'de toml::Value); struct SA<'de> (slice::Iter<'de, toml::Value>); @@ -55,11 +69,7 @@ impl<'de> MapAccess<'de> for MA<'de> { (&mut self, seed: K) -> Result, Error> { Ok(if let Some((k, _v)) = self.0.peek() { - Some(seed.deserialize({ - let q : serde::de::value::StrDeserializer<'_, Error> = - k.as_str().into_deserializer(); - q - })?) + Some(str_deserialize(seed, k)?) } else { None }) @@ -73,6 +83,43 @@ impl<'de> MapAccess<'de> for MA<'de> { } } +struct EA<'de> { k: &'de str, v: &'de toml::Value } + +impl<'de> EnumAccess<'de> for EA<'de> { + type Error = Error; + type Variant = TomlDe<'de>; + #[throws(Error)] + fn variant_seed> + (self, seed: V) -> (V::Value, TomlDe<'de>) + { + (str_deserialize(seed, self.k)?, + TomlDe(self.v)) + } +} + +impl<'de> VariantAccess<'de> for TomlDe<'de> { + type Error = Error; + #[throws(Error)] + fn unit_variant(self) { } + + #[throws(Error)] + fn newtype_variant_seed> + (self, seed: S) -> S::Value + { + seed.deserialize(self)? + } + + #[throws(Error)] + fn tuple_variant>(self, _: usize, v: V) -> V::Value { + visit(v, &self.0)? + } + + #[throws(Error)] + fn struct_variant>(self, _:&[&str], v: V) -> V::Value { + visit(v, &self.0)? + } +} + #[throws(Error)] fn visit<'de, V: Visitor<'de>>(v: V, tv: &'de toml::Value) -> V::Value { type TV = toml::Value; @@ -101,10 +148,27 @@ impl<'de> Deserializer<'de> for TomlDe<'de> { // the relevant struct key. visitor.visit_some(self)? } + #[throws(Error)] + fn deserialize_enum> + (self, _:&str, _:&[&str], v: V) -> V::Value + { + type TV = toml::Value; + match &self.0 { + TV::String(s) => return v.visit_enum(s.as_str().into_deserializer()), + TV::Table(s) => if_chain! { + if let Some((k, v)) = s.next(); + if let None = s.next(); + then { return v.visit_enum(EA { k, v })? } + }, + _ => {}, + } + // hopefully the format will figure it out, or produce an error + visit(v, &self.0)? + } forward_to_deserialize_any! { bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any + tuple_struct map struct identifier ignored_any } } -- 2.30.2