From 56edb3a50fb4168ed76a3795f0ed774a754b6c32 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 20:02:56 +0200 Subject: Split traits module into submodules --- dhall/src/traits/deserialize.rs | 43 +++++++++++++++++ dhall/src/traits/mod.rs | 4 ++ dhall/src/traits/static_type.rs | 104 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 dhall/src/traits/deserialize.rs create mode 100644 dhall/src/traits/mod.rs create mode 100644 dhall/src/traits/static_type.rs (limited to 'dhall/src/traits') diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs new file mode 100644 index 0000000..8d1f565 --- /dev/null +++ b/dhall/src/traits/deserialize.rs @@ -0,0 +1,43 @@ +use crate::error::*; +use crate::expr::*; + +pub trait Deserialize<'a>: Sized { + fn from_str(s: &'a str, ty: Option<&Type>) -> Result; +} + +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 { + Ok(Parsed::parse_str(s).map_err(|_| ())?) + } +} + +impl<'a> Deserialize<'a> for Resolved { + /// Parses and resolves the provided string. Ignores the + /// provided type. + fn from_str(s: &'a str, ty: Option<&Type>) -> Result { + Ok(Parsed::from_str(s, ty)?.resolve().map_err(|_| ())?) + } +} + +impl<'a> Deserialize<'a> for Typed { + /// Parses, resolves and typechecks the provided string. + fn from_str(s: &'a str, ty: Option<&Type>) -> Result { + // TODO: compare with provided type + Ok(Resolved::from_str(s, ty)?.typecheck().map_err(|_| ())?) + } +} + +impl<'a> Deserialize<'a> for Normalized { + /// Parses, resolves, typechecks and normalizes the provided string. + fn from_str(s: &'a str, ty: Option<&Type>) -> Result { + Ok(Typed::from_str(s, ty)?.normalize()) + } +} + +impl<'a> Deserialize<'a> for Type { + fn from_str(s: &'a str, ty: Option<&Type>) -> Result { + Ok(Normalized::from_str(s, ty)?.into_type()) + } +} diff --git a/dhall/src/traits/mod.rs b/dhall/src/traits/mod.rs new file mode 100644 index 0000000..4ce8f97 --- /dev/null +++ b/dhall/src/traits/mod.rs @@ -0,0 +1,4 @@ +mod deserialize; +mod static_type; +pub use deserialize::Deserialize; +pub use static_type::{SimpleStaticType, StaticType}; diff --git a/dhall/src/traits/static_type.rs b/dhall/src/traits/static_type.rs new file mode 100644 index 0000000..b402ca9 --- /dev/null +++ b/dhall/src/traits/static_type.rs @@ -0,0 +1,104 @@ +use crate::expr::*; +use dhall_core::*; +use dhall_generator::*; + +pub trait StaticType { + fn get_static_type() -> Type; +} + +/// Trait for rust types that can be represented in dhall in +/// a single way, independent of the value. A typical example is `Option`, +/// represented by the dhall expression `Optional Bool`. A typical counterexample +/// is `HashMap` because dhall cannot represent records with a +/// variable number of fields. +pub trait SimpleStaticType { + fn get_simple_static_type() -> SimpleType; +} + +fn mktype(x: SubExpr) -> SimpleType { + SimpleType(x) +} + +impl StaticType for T { + fn get_static_type() -> Type { + crate::expr::Normalized( + T::get_simple_static_type().into(), + Type::const_type(), + ) + .into_type() + } +} + +impl StaticType for SimpleType { + fn get_static_type() -> Type { + Type::const_type() + } +} + +impl SimpleStaticType for bool { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Bool)) + } +} + +impl SimpleStaticType for Natural { + 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 String { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Text)) + } +} + +impl SimpleStaticType for (A, B) { + fn get_simple_static_type() -> SimpleType { + let ta: SubExpr<_, _> = A::get_simple_static_type().into(); + let tb: SubExpr<_, _> = B::get_simple_static_type().into(); + mktype(dhall_expr!({ _1: ta, _2: tb })) + } +} + +impl SimpleStaticType for Option { + fn get_simple_static_type() -> SimpleType { + let t: SubExpr<_, _> = T::get_simple_static_type().into(); + mktype(dhall_expr!(Optional t)) + } +} + +impl SimpleStaticType for Vec { + fn get_simple_static_type() -> SimpleType { + let t: SubExpr<_, _> = T::get_simple_static_type().into(); + mktype(dhall_expr!(List t)) + } +} + +impl<'a, T: SimpleStaticType> SimpleStaticType for &'a T { + fn get_simple_static_type() -> SimpleType { + T::get_simple_static_type() + } +} + +impl SimpleStaticType for std::marker::PhantomData { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!({})) + } +} + +impl SimpleStaticType + for std::result::Result +{ + fn get_simple_static_type() -> SimpleType { + let tt: SubExpr<_, _> = T::get_simple_static_type().into(); + let te: SubExpr<_, _> = E::get_simple_static_type().into(); + mktype(dhall_expr!(< Ok: tt | Err: te>)) + } +} -- cgit v1.2.3