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<Self>;
+}
+
+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> {
+        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<Self> {
+        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<Self> {
+        // 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<Self> {
+        Ok(Typed::from_str(s, ty)?.normalize())
+    }
+}
+
+impl<'a> Deserialize<'a> for Type {
+    fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+        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<bool>`,
+/// represented by the dhall expression `Optional Bool`. A typical counterexample
+/// is `HashMap<Text, bool>` because dhall cannot represent records with a
+/// variable number of fields.
+pub trait SimpleStaticType {
+    fn get_simple_static_type() -> SimpleType;
+}
+
+fn mktype(x: SubExpr<X, X>) -> SimpleType {
+    SimpleType(x)
+}
+
+impl<T: SimpleStaticType> 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<A: SimpleStaticType, B: SimpleStaticType> 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<T: SimpleStaticType> SimpleStaticType for Option<T> {
+    fn get_simple_static_type() -> SimpleType {
+        let t: SubExpr<_, _> = T::get_simple_static_type().into();
+        mktype(dhall_expr!(Optional t))
+    }
+}
+
+impl<T: SimpleStaticType> SimpleStaticType for Vec<T> {
+    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<T> SimpleStaticType for std::marker::PhantomData<T> {
+    fn get_simple_static_type() -> SimpleType {
+        mktype(dhall_expr!({}))
+    }
+}
+
+impl<T: SimpleStaticType, E: SimpleStaticType> SimpleStaticType
+    for std::result::Result<T, E>
+{
+    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