summaryrefslogtreecommitdiff
path: root/dhall/src/traits
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dhall/src/traits.rs77
-rw-r--r--dhall/src/traits/deserialize.rs46
-rw-r--r--dhall/src/traits/mod.rs4
-rw-r--r--dhall/src/traits/static_type.rs128
4 files changed, 178 insertions, 77 deletions
diff --git a/dhall/src/traits.rs b/dhall/src/traits.rs
deleted file mode 100644
index 64e07d9..0000000
--- a/dhall/src/traits.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use dhall_core::*;
-use dhall_generator::*;
-
-#[derive(Debug, Clone)]
-pub enum ConversionError {}
-
-pub trait StaticType {
- fn get_type() -> DhallExpr;
- // fn as_dhall(&self) -> DhallExpr;
- // fn from_dhall(e: DhallExpr) -> Result<Self, DhallConversionError>;
-}
-
-impl StaticType for bool {
- fn get_type() -> DhallExpr {
- dhall_expr!(Bool)
- }
-}
-
-impl StaticType for Natural {
- fn get_type() -> DhallExpr {
- dhall_expr!(Natural)
- }
-}
-
-impl StaticType for Integer {
- fn get_type() -> DhallExpr {
- dhall_expr!(Integer)
- }
-}
-
-impl StaticType for String {
- fn get_type() -> DhallExpr {
- dhall_expr!(Text)
- }
-}
-
-impl<A: StaticType, B: StaticType> StaticType for (A, B) {
- fn get_type() -> DhallExpr {
- let ta = A::get_type();
- let tb = B::get_type();
- dhall_expr!({ _1: ta, _2: tb })
- }
-}
-
-impl<T: StaticType> StaticType for Option<T> {
- fn get_type() -> DhallExpr {
- let t = T::get_type();
- dhall_expr!(Optional t)
- }
-}
-
-impl<T: StaticType> StaticType for Vec<T> {
- fn get_type() -> DhallExpr {
- let t = T::get_type();
- dhall_expr!(List t)
- }
-}
-
-impl<'a, T: StaticType> StaticType for &'a T {
- fn get_type() -> DhallExpr {
- T::get_type()
- }
-}
-
-impl<T> StaticType for std::marker::PhantomData<T> {
- fn get_type() -> DhallExpr {
- dhall_expr!({})
- }
-}
-
-impl<T: StaticType, E: StaticType> StaticType for Result<T, E> {
- fn get_type() -> DhallExpr {
- let tt = T::get_type();
- let te = E::get_type();
- dhall_expr!(< Ok: tt | Err: te>)
- }
-}
diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs
new file mode 100644
index 0000000..1fbdfe1
--- /dev/null
+++ b/dhall/src/traits/deserialize.rs
@@ -0,0 +1,46 @@
+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, _: Option<&Type>) -> Result<Self> {
+ Ok(Parsed::parse_str(s)?)
+ }
+}
+
+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()?)
+ }
+}
+
+impl<'a> Deserialize<'a> for Typed {
+ /// Parses, resolves and typechecks the provided string.
+ fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+ let resolved = Resolved::from_str(s, ty)?;
+ match ty {
+ None => Ok(resolved.typecheck()?),
+ Some(t) => Ok(resolved.typecheck_with(t)?),
+ }
+ }
+}
+
+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..6c41e3f
--- /dev/null
+++ b/dhall/src/traits/static_type.rs
@@ -0,0 +1,128 @@
+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 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))
+ }
+}
+
+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>))
+ }
+}