From 7ac061b5ddf15ffe3fc4f36b64138b7431429758 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Thu, 9 May 2019 22:27:17 +0200 Subject: Rewrite Deserialize trait around new Value and Type --- dhall/src/api/mod.rs | 80 +++++++++++++++++++++++++++++-------- dhall/src/api/serde.rs | 15 +++---- dhall/src/api/traits/deserialize.rs | 53 ------------------------ dhall/src/api/traits/mod.rs | 2 - dhall/src/lib.rs | 1 - dhall/src/phase/mod.rs | 8 +--- dhall/src/tests.rs | 2 +- 7 files changed, 73 insertions(+), 88 deletions(-) delete mode 100644 dhall/src/api/traits/deserialize.rs delete mode 100644 dhall/src/api/traits/mod.rs (limited to 'dhall') diff --git a/dhall/src/api/mod.rs b/dhall/src/api/mod.rs index 72789d9..233d7cf 100644 --- a/dhall/src/api/mod.rs +++ b/dhall/src/api/mod.rs @@ -1,16 +1,43 @@ mod serde; pub(crate) mod static_type; -pub(crate) mod traits; -// pub struct Value(crate::phase::Normalized); +pub use value::Value; + +mod value { + use super::Type; + use crate::error::Result; + use crate::phase::{NormalizedSubExpr, Parsed, Typed}; + + // A Dhall value + pub struct Value(Typed); + + impl Value { + pub fn from_str(s: &str, ty: Option<&Type>) -> Result { + let resolved = Parsed::parse_str(s)?.resolve()?; + let typed = match ty { + None => resolved.typecheck()?, + Some(t) => resolved.typecheck_with(&t.to_type())?, + }; + Ok(Value(typed)) + } + pub(crate) fn to_expr(&self) -> NormalizedSubExpr { + self.0.to_expr() + } + pub(crate) fn to_typed(&self) -> Typed { + self.0.clone() + } + } +} pub use typ::Type; mod typ { + use dhall_syntax::Builtin; + use crate::core::thunk::{Thunk, TypeThunk}; use crate::core::value::Value; + use crate::error::Result; use crate::phase::{NormalizedSubExpr, Typed}; - use dhall_syntax::Builtin; /// A Dhall expression representing a type. /// @@ -72,18 +99,38 @@ mod typ { pub(crate) fn to_expr(&self) -> NormalizedSubExpr { self.0.to_expr() } + pub(crate) fn to_type(&self) -> crate::phase::Type { + self.0.to_type() + } + } + + impl crate::de::Deserialize for Type { + fn from_dhall(v: &crate::api::Value) -> Result { + Ok(Type(v.to_typed())) + } } } /// Deserialization of Dhall expressions into Rust pub mod de { pub use super::static_type::StaticType; - pub use super::Type; - #[doc(hidden)] - pub use crate::traits::Deserialize; + pub use super::{Type, Value}; + use crate::error::Result; #[doc(hidden)] pub use dhall_proc_macros::StaticType; + /// A data structure that can be deserialized from a Dhall expression + /// + /// This is automatically implemented for any type that [serde][serde] + /// can deserialize. + /// + /// This trait cannot be implemented manually. + // TODO: seal trait + pub trait Deserialize: Sized { + /// See [dhall::de::from_str][crate::de::from_str] + fn from_dhall(v: &Value) -> Result; + } + /// Deserialize an instance of type T from a string of Dhall text. /// /// This will recursively resolve all imports in the expression, and @@ -93,11 +140,11 @@ pub mod de { /// /// If a type is provided, this additionally checks that the provided /// expression has that type. - pub fn from_str<'a, T: Deserialize<'a>>( - s: &'a str, - ty: Option<&crate::phase::Type>, - ) -> crate::error::Result { - T::from_str(s, ty) + pub fn from_str(s: &str, ty: Option<&Type>) -> Result + where + T: Deserialize, + { + T::from_dhall(&Value::from_str(s, ty)?) } /// Deserialize an instance of type T from a string of Dhall text, @@ -107,11 +154,10 @@ pub mod de { /// typecheck it before deserialization. Relative imports will be resolved relative to the /// provided file. More control over this process is not yet available /// but will be in a coming version of this crate. - pub fn from_str_auto_type<'a, T: Deserialize<'a> + StaticType>( - s: &'a str, - ) -> crate::error::Result { - // from_str(s, Some(&::static_type())) - // TODO - from_str(s, None) + pub fn from_str_auto_type(s: &str) -> Result + where + T: Deserialize + StaticType, + { + from_str(s, Some(&::static_type())) } } diff --git a/dhall/src/api/serde.rs b/dhall/src/api/serde.rs index 93921ba..7be77c0 100644 --- a/dhall/src/api/serde.rs +++ b/dhall/src/api/serde.rs @@ -1,13 +1,14 @@ +use crate::api::de::{Deserialize, Value}; use crate::error::{Error, Result}; -use crate::phase::{Normalized, Type}; -use crate::traits::Deserialize; -use dhall_syntax::*; +use dhall_syntax::{SubExpr,ExprF, X}; use std::borrow::Cow; -impl<'a, T: serde::Deserialize<'a>> Deserialize<'a> for T { - fn from_str(s: &'a str, ty: Option<&Type>) -> Result { - let expr = Normalized::from_str(s, ty)?; - T::deserialize(Deserializer(Cow::Owned(expr.to_expr()))) +impl<'a, T> Deserialize for T +where + T: serde::Deserialize<'a>, +{ + fn from_dhall(v: &Value) -> Result { + T::deserialize(Deserializer(Cow::Owned(v.to_expr()))) } } diff --git a/dhall/src/api/traits/deserialize.rs b/dhall/src/api/traits/deserialize.rs deleted file mode 100644 index 9673cf9..0000000 --- a/dhall/src/api/traits/deserialize.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::error::*; -use crate::phase::*; - -/// A data structure that can be deserialized from a Dhall expression -/// -/// This is automatically implemented for any type that [serde][serde] -/// can deserialize. -/// -/// This trait cannot be implemented manually. -pub trait Deserialize<'de>: Sized { - /// See [dhall::de::from_str][crate::de::from_str] - fn from_str(s: &'de str, ty: Option<&Type>) -> Result; -} - -impl<'de> Deserialize<'de> for Parsed { - /// Simply parses the provided string. Ignores the - /// provided type. - fn from_str(s: &'de str, _: Option<&Type>) -> Result { - Ok(Parsed::parse_str(s)?) - } -} - -impl<'de> Deserialize<'de> for Resolved { - /// Parses and resolves the provided string. Ignores the - /// provided type. - fn from_str(s: &'de str, ty: Option<&Type>) -> Result { - Ok(Parsed::from_str(s, ty)?.resolve()?) - } -} - -impl<'de> Deserialize<'de> for Typed { - /// Parses, resolves and typechecks the provided string. - fn from_str(s: &'de str, ty: Option<&Type>) -> Result { - let resolved = Resolved::from_str(s, ty)?; - match ty { - None => Ok(resolved.typecheck()?), - Some(t) => Ok(resolved.typecheck_with(t)?), - } - } -} - -impl<'de> Deserialize<'de> for Normalized { - /// Parses, resolves, typechecks and normalizes the provided string. - fn from_str(s: &'de str, ty: Option<&Type>) -> Result { - Ok(Typed::from_str(s, ty)?.normalize()) - } -} - -impl<'de> Deserialize<'de> for Type { - fn from_str(s: &'de str, ty: Option<&Type>) -> Result { - Ok(Normalized::from_str(s, ty)?.to_type()) - } -} diff --git a/dhall/src/api/traits/mod.rs b/dhall/src/api/traits/mod.rs deleted file mode 100644 index 3fd21e4..0000000 --- a/dhall/src/api/traits/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod deserialize; -pub use deserialize::Deserialize; diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index c25fc82..29da609 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -128,6 +128,5 @@ pub(crate) mod api; pub(crate) mod core; pub mod error; pub(crate) mod phase; -pub(crate) use api::traits; pub use api::*; diff --git a/dhall/src/phase/mod.rs b/dhall/src/phase/mod.rs index 5262a27..d7cec67 100644 --- a/dhall/src/phase/mod.rs +++ b/dhall/src/phase/mod.rs @@ -50,7 +50,7 @@ pub(crate) enum Typed { pub(crate) struct Normalized(pub(crate) Typed); #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Type(pub(crate) Typed); +pub(crate) struct Type(pub(crate) Typed); impl Parsed { pub fn parse_file(f: &Path) -> Result { @@ -202,9 +202,6 @@ impl Type { } impl Normalized { - pub(crate) fn to_expr(&self) -> NormalizedSubExpr { - self.0.to_expr() - } #[allow(dead_code)] pub(crate) fn to_expr_alpha(&self) -> NormalizedSubExpr { self.0.to_expr_alpha() @@ -212,9 +209,6 @@ impl Normalized { pub(crate) fn to_value(&self) -> Value { self.0.to_value() } - pub(crate) fn to_type(&self) -> Type { - self.0.to_type() - } pub(crate) fn into_typed(self) -> Typed { self.0 } diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index a958e48..76e2e26 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -108,7 +108,7 @@ pub fn run_test( // Round-trip pretty-printer let expr_string = expr.to_string(); - let expr: Parsed = crate::de::from_str(&expr_string, None)?; + let expr: Parsed = Parsed::parse_str(&expr_string)?; assert_eq!(expr, expected); return Ok(()); -- cgit v1.2.3