From 82d62c4d7d423817a4fd9d6294d27d18d60bcd22 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 11 Apr 2019 13:11:52 +0200 Subject: Add basic deserialization support Closes #13 --- dhall/Cargo.toml | 3 -- dhall/src/error.rs | 3 ++ dhall/src/lib.rs | 7 ++--- dhall/src/serde.rs | 68 ++++++++++++++++++++++++++++++++++++++--- dhall/src/traits/deserialize.rs | 2 +- dhall/src/traits/static_type.rs | 24 +++++++++++++++ 6 files changed, 95 insertions(+), 12 deletions(-) (limited to 'dhall') diff --git a/dhall/Cargo.toml b/dhall/Cargo.toml index a7c21dd..7f695d4 100644 --- a/dhall/Cargo.toml +++ b/dhall/Cargo.toml @@ -5,9 +5,6 @@ authors = ["NanoTech ", "Nadrieril > Deserialize<'a> for T { - fn from_str(_s: &'a str, _ty: Option<&Type>) -> Result { - unimplemented!() + fn from_str(s: &'a str, ty: Option<&Type>) -> Result { + let expr = Normalized::from_str(s, ty)?; + T::deserialize(Deserializer(Cow::Owned(expr.0))) + } +} + +struct Deserializer<'a>(Cow<'a, SubExpr>); + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self + where + T: std::fmt::Display, + { + Error::Deserialize(msg.to_string()) + } +} + +impl<'de: 'a, 'a> serde::de::IntoDeserializer<'de, Error> for Deserializer<'a> { + type Deserializer = Deserializer<'a>; + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de: 'a, 'a> serde::Deserializer<'de> for Deserializer<'a> { + type Error = Error; + fn deserialize_any(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + use std::convert::TryInto; + use ExprF::*; + match self.0.as_ref().as_ref() { + NaturalLit(n) => match (*n).try_into() { + Ok(n64) => visitor.visit_u64(n64), + Err(_) => match (*n).try_into() { + Ok(n32) => visitor.visit_u32(n32), + Err(_) => unimplemented!(), + }, + }, + IntegerLit(n) => match (*n).try_into() { + Ok(n64) => visitor.visit_i64(n64), + Err(_) => match (*n).try_into() { + Ok(n32) => visitor.visit_i32(n32), + Err(_) => unimplemented!(), + }, + }, + RecordLit(m) => visitor.visit_map( + serde::de::value::MapDeserializer::new(m.iter().map( + |(k, v)| (k.as_ref(), Deserializer(Cow::Borrowed(v))), + )), + ), + _ => unimplemented!(), + } + } + + serde::forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any } } diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs index 5271a65..1fbdfe1 100644 --- a/dhall/src/traits/deserialize.rs +++ b/dhall/src/traits/deserialize.rs @@ -8,7 +8,7 @@ pub trait Deserialize<'a>: Sized { impl<'a> Deserialize<'a> for Parsed { /// Simply parses the provided string. Ignores the /// provided type. - fn from_str(s: &'a str, _ty: Option<&Type>) -> Result { + fn from_str(s: &'a str, _: Option<&Type>) -> Result { Ok(Parsed::parse_str(s)?) } } diff --git a/dhall/src/traits/static_type.rs b/dhall/src/traits/static_type.rs index b402ca9..6c41e3f 100644 --- a/dhall/src/traits/static_type.rs +++ b/dhall/src/traits/static_type.rs @@ -47,12 +47,36 @@ impl SimpleStaticType for Natural { } } +impl SimpleStaticType for u32 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Natural)) + } +} + +impl SimpleStaticType for u64 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Natural)) + } +} + impl SimpleStaticType for Integer { fn get_simple_static_type() -> SimpleType { mktype(dhall_expr!(Integer)) } } +impl SimpleStaticType for i32 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Integer)) + } +} + +impl SimpleStaticType for i64 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Integer)) + } +} + impl SimpleStaticType for String { fn get_simple_static_type() -> SimpleType { mktype(dhall_expr!(Text)) -- cgit v1.2.3