From e1a30c6f248c0c17c97598290a0d94993dbb0325 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 19:16:11 +0200 Subject: Add SimpleType and SimpeStaticType. Derive the latter --- dhall/src/traits.rs | 109 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 39 deletions(-) (limited to 'dhall/src/traits.rs') diff --git a/dhall/src/traits.rs b/dhall/src/traits.rs index 64e07d9..4925457 100644 --- a/dhall/src/traits.rs +++ b/dhall/src/traits.rs @@ -1,77 +1,108 @@ +use crate::expr::*; use dhall_core::*; use dhall_generator::*; +use std::borrow::Cow; #[derive(Debug, Clone)] pub enum ConversionError {} pub trait StaticType { - fn get_type() -> DhallExpr; - // fn as_dhall(&self) -> DhallExpr; - // fn from_dhall(e: DhallExpr) -> Result; + fn get_static_type() -> Type; } -impl StaticType for bool { - fn get_type() -> DhallExpr { - dhall_expr!(Bool) +/// 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 StaticType for Natural { - fn get_type() -> DhallExpr { - dhall_expr!(Natural) +impl SimpleStaticType for Natural { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Natural)) } } -impl StaticType for Integer { - fn get_type() -> DhallExpr { - dhall_expr!(Integer) +impl SimpleStaticType for Integer { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Integer)) } } -impl StaticType for String { - fn get_type() -> DhallExpr { - dhall_expr!(Text) +impl SimpleStaticType for String { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!(Text)) } } -impl 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 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 StaticType for Option { - fn get_type() -> DhallExpr { - let t = T::get_type(); - dhall_expr!(Optional t) +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 StaticType for Vec { - fn get_type() -> DhallExpr { - let t = T::get_type(); - dhall_expr!(List 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: StaticType> StaticType for &'a T { - fn get_type() -> DhallExpr { - T::get_type() +impl<'a, T: SimpleStaticType> SimpleStaticType for &'a T { + fn get_simple_static_type() -> SimpleType { + T::get_simple_static_type() } } -impl StaticType for std::marker::PhantomData { - fn get_type() -> DhallExpr { - dhall_expr!({}) +impl SimpleStaticType for std::marker::PhantomData { + fn get_simple_static_type() -> SimpleType { + mktype(dhall_expr!({})) } } -impl StaticType for Result { - fn get_type() -> DhallExpr { - let tt = T::get_type(); - let te = E::get_type(); - dhall_expr!(< Ok: tt | Err: te>) +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.3.1 From ff12918696181f1b0f2b8272944044e27c89e319 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 19:18:25 +0200 Subject: Add a new Deserialize trait for reading dhall values --- dhall/src/lib.rs | 14 ++++++++++++++ dhall/src/traits.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) (limited to 'dhall/src/traits.rs') diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 3bfc46f..b49d1c1 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -21,7 +21,21 @@ mod imports; mod normalize; mod traits; mod typecheck; +pub use crate::traits::Deserialize; pub use crate::traits::SimpleStaticType; pub use crate::traits::StaticType; pub use dhall_generator::SimpleStaticType; pub mod expr; + +pub fn from_str<'a, T: Deserialize<'a>>( + s: &'a str, + ty: Option<&crate::expr::Type>, +) -> crate::traits::Result { + T::from_str(s, ty) +} + +pub fn from_str_auto_type<'a, T: Deserialize<'a> + StaticType>( + s: &'a str, +) -> crate::traits::Result { + from_str(s, Some(&::get_static_type())) +} diff --git a/dhall/src/traits.rs b/dhall/src/traits.rs index 4925457..370632e 100644 --- a/dhall/src/traits.rs +++ b/dhall/src/traits.rs @@ -19,6 +19,56 @@ pub trait SimpleStaticType { fn get_simple_static_type() -> SimpleType; } +pub type Error = (); +pub type Result = std::result::Result; + +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()) + } +} + fn mktype(x: SubExpr) -> SimpleType { SimpleType(x) } -- cgit v1.3.1 From 730d99adf2d4a7f222a71d687ea942545a7038fd Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 19:55:50 +0200 Subject: Add error submodule --- dhall/src/error.rs | 3 +++ dhall/src/lib.rs | 5 +++-- dhall/src/serde.rs | 2 +- dhall/src/traits.rs | 6 +----- 4 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 dhall/src/error.rs (limited to 'dhall/src/traits.rs') diff --git a/dhall/src/error.rs b/dhall/src/error.rs new file mode 100644 index 0000000..ef8dd34 --- /dev/null +++ b/dhall/src/error.rs @@ -0,0 +1,3 @@ +// TODO +pub type Error = (); +pub type Result = std::result::Result; diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index ababc5d..c218aeb 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -131,18 +131,19 @@ pub use crate::traits::Deserialize; pub use crate::traits::SimpleStaticType; pub use crate::traits::StaticType; pub use dhall_generator::SimpleStaticType; +pub mod error; pub mod expr; pub mod serde; pub fn from_str<'a, T: Deserialize<'a>>( s: &'a str, ty: Option<&crate::expr::Type>, -) -> crate::traits::Result { +) -> crate::error::Result { T::from_str(s, ty) } pub fn from_str_auto_type<'a, T: Deserialize<'a> + StaticType>( s: &'a str, -) -> crate::traits::Result { +) -> crate::error::Result { from_str(s, Some(&::get_static_type())) } diff --git a/dhall/src/serde.rs b/dhall/src/serde.rs index 278ea7a..4ac4f3d 100644 --- a/dhall/src/serde.rs +++ b/dhall/src/serde.rs @@ -1,6 +1,6 @@ +use crate::error::Result; use crate::expr::Type; use crate::traits::Deserialize; -use crate::traits::Result; impl<'a, T: serde::Deserialize<'a>> Deserialize<'a> for T { fn from_str(_s: &'a str, _ty: Option<&Type>) -> Result { diff --git a/dhall/src/traits.rs b/dhall/src/traits.rs index 370632e..328cbbc 100644 --- a/dhall/src/traits.rs +++ b/dhall/src/traits.rs @@ -1,11 +1,9 @@ +use crate::error::*; use crate::expr::*; use dhall_core::*; use dhall_generator::*; use std::borrow::Cow; -#[derive(Debug, Clone)] -pub enum ConversionError {} - pub trait StaticType { fn get_static_type() -> Type; } @@ -19,8 +17,6 @@ pub trait SimpleStaticType { fn get_simple_static_type() -> SimpleType; } -pub type Error = (); -pub type Result = std::result::Result; pub trait Deserialize<'a>: Sized { fn from_str(s: &'a str, ty: Option<&Type>) -> Result; -- cgit v1.3.1 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.rs | 154 ---------------------------------------- dhall/src/traits/deserialize.rs | 43 +++++++++++ dhall/src/traits/mod.rs | 4 ++ dhall/src/traits/static_type.rs | 104 +++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 154 deletions(-) delete mode 100644 dhall/src/traits.rs 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.rs') diff --git a/dhall/src/traits.rs b/dhall/src/traits.rs deleted file mode 100644 index 328cbbc..0000000 --- a/dhall/src/traits.rs +++ /dev/null @@ -1,154 +0,0 @@ -use crate::error::*; -use crate::expr::*; -use dhall_core::*; -use dhall_generator::*; -use std::borrow::Cow; - -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; -} - - -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()) - } -} - -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>)) - } -} 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.3.1