diff options
author | Nadrieril | 2019-04-11 13:11:52 +0200 |
---|---|---|
committer | Nadrieril | 2019-04-11 13:11:52 +0200 |
commit | 82d62c4d7d423817a4fd9d6294d27d18d60bcd22 (patch) | |
tree | 887b4af84bc2c69886616a4a9c8aa27fa846238a | |
parent | 9a060908aae564e7155259a4e12d63be3fb97d9b (diff) |
Add basic deserialization support
Closes #13
-rw-r--r-- | dhall/Cargo.toml | 3 | ||||
-rw-r--r-- | dhall/src/error.rs | 3 | ||||
-rw-r--r-- | dhall/src/lib.rs | 7 | ||||
-rw-r--r-- | dhall/src/serde.rs | 68 | ||||
-rw-r--r-- | dhall/src/traits/deserialize.rs | 2 | ||||
-rw-r--r-- | dhall/src/traits/static_type.rs | 24 | ||||
-rw-r--r-- | dhall_core/src/core.rs | 1 | ||||
-rw-r--r-- | dhall_core/src/label.rs | 3 |
8 files changed, 98 insertions, 13 deletions
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 <nanotech@nanotechcorp.net>", "Nadrieril <nadrieril@users.n edition = "2018" build = "build.rs" -[lib] -doctest = false - [features] nothreads = [] # disable threads for tarpaulin diff --git a/dhall/src/error.rs b/dhall/src/error.rs index 9e64b7e..cfd6f09 100644 --- a/dhall/src/error.rs +++ b/dhall/src/error.rs @@ -25,5 +25,8 @@ quick_error! { from() display("{:?}", err) } + Deserialize(err: String) { + display("{}", err) + } } } diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index c218aeb..8af5af9 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -39,14 +39,13 @@ //! //! #[derive(Debug, Deserialize, SimpleStaticType)] //! struct Point { -//! x: usize, -//! y: usize, +//! x: u64, +//! y: u64, //! } //! //! fn main() { //! // Some dhall data -//! // ./Point can be populated using Point::get_type().to_string() -//! let data = "{ x = 1, y = 1 + 1 } : ./Point"; +//! let data = "{ x = 1, y = 1 + 1 }"; //! //! // Convert the dhall string to a Point. //! let point: Point = diff --git a/dhall/src/serde.rs b/dhall/src/serde.rs index 4ac4f3d..196bda1 100644 --- a/dhall/src/serde.rs +++ b/dhall/src/serde.rs @@ -1,9 +1,69 @@ -use crate::error::Result; -use crate::expr::Type; +use crate::error::{Error, Result}; +use crate::expr::{Normalized, Type}; use crate::traits::Deserialize; +use dhall_core::*; +use std::borrow::Cow; impl<'a, T: serde::Deserialize<'a>> Deserialize<'a> for T { - fn from_str(_s: &'a str, _ty: Option<&Type>) -> Result<Self> { - unimplemented!() + fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> { + let expr = Normalized::from_str(s, ty)?; + T::deserialize(Deserializer(Cow::Owned(expr.0))) + } +} + +struct Deserializer<'a>(Cow<'a, SubExpr<X, X>>); + +impl serde::de::Error for Error { + fn custom<T>(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<V>(self, visitor: V) -> Result<V::Value> + 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<Self> { + fn from_str(s: &'a str, _: Option<&Type>) -> Result<Self> { 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)) diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index 39dea37..03a34f1 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -3,7 +3,6 @@ use crate::*; use std::collections::BTreeMap; use std::rc::Rc; -pub type Int = isize; pub type Integer = isize; pub type Natural = usize; pub type Double = NaiveDouble; diff --git a/dhall_core/src/label.rs b/dhall_core/src/label.rs index 9dc2816..43c3f53 100644 --- a/dhall_core/src/label.rs +++ b/dhall_core/src/label.rs @@ -28,4 +28,7 @@ impl Label { pub fn from_str(s: &str) -> Label { Label(s.into()) } + pub fn as_ref(&self) -> &str { + self.0.as_ref() + } } |