From 5b91eaa9d6b70a2ac72fe19f2d21871c8d94b017 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 6 May 2019 23:21:19 +0200 Subject: Move api-related modules into an api module --- dhall/src/api/mod.rs | 38 +++++++++ dhall/src/api/serde.rs | 69 ++++++++++++++++ dhall/src/api/traits/deserialize.rs | 53 +++++++++++++ dhall/src/api/traits/dynamic_type.rs | 32 ++++++++ dhall/src/api/traits/mod.rs | 6 ++ dhall/src/api/traits/static_type.rs | 149 +++++++++++++++++++++++++++++++++++ dhall/src/lib.rs | 41 +--------- dhall/src/serde.rs | 69 ---------------- dhall/src/traits/deserialize.rs | 53 ------------- dhall/src/traits/dynamic_type.rs | 32 -------- dhall/src/traits/mod.rs | 6 -- dhall/src/traits/static_type.rs | 149 ----------------------------------- 12 files changed, 350 insertions(+), 347 deletions(-) create mode 100644 dhall/src/api/mod.rs create mode 100644 dhall/src/api/serde.rs create mode 100644 dhall/src/api/traits/deserialize.rs create mode 100644 dhall/src/api/traits/dynamic_type.rs create mode 100644 dhall/src/api/traits/mod.rs create mode 100644 dhall/src/api/traits/static_type.rs delete mode 100644 dhall/src/serde.rs delete mode 100644 dhall/src/traits/deserialize.rs delete mode 100644 dhall/src/traits/dynamic_type.rs delete mode 100644 dhall/src/traits/mod.rs delete mode 100644 dhall/src/traits/static_type.rs (limited to 'dhall/src') diff --git a/dhall/src/api/mod.rs b/dhall/src/api/mod.rs new file mode 100644 index 0000000..1522c9c --- /dev/null +++ b/dhall/src/api/mod.rs @@ -0,0 +1,38 @@ +mod serde; +pub(crate) mod traits; + +/// Deserialization of Dhall expressions into Rust +pub mod de { + pub use crate::traits::{Deserialize, SimpleStaticType, StaticType}; + #[doc(hidden)] + pub use dhall_proc_macros::SimpleStaticType; + + /// Deserialize an instance of type T from a string of Dhall text. + /// + /// This will recursively resolve all imports in the expression, and + /// 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. + /// + /// 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) + } + + /// Deserialize an instance of type T from a string of Dhall text, + /// additionally checking that it matches the type of T. + /// + /// This will recursively resolve all imports in the expression, and + /// 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(&::get_static_type())) + } +} diff --git a/dhall/src/api/serde.rs b/dhall/src/api/serde.rs new file mode 100644 index 0000000..93921ba --- /dev/null +++ b/dhall/src/api/serde.rs @@ -0,0 +1,69 @@ +use crate::error::{Error, Result}; +use crate::phase::{Normalized, Type}; +use crate::traits::Deserialize; +use dhall_syntax::*; +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()))) + } +} + +struct Deserializer<'a>(Cow<'a, SubExpr>); + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self + where + T: std::fmt::Display, + { + Error::Deserialize(msg.to_string()) + } +} + +impl<'de: 'a, 'a> serde::de::IntoDeserializer<'de, Error> for Deserializer<'a> { + type Deserializer = Deserializer<'a>; + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de: 'a, 'a> serde::Deserializer<'de> for Deserializer<'a> { + type Error = Error; + fn deserialize_any(self, visitor: V) -> Result + where + V: serde::de::Visitor<'de>, + { + use std::convert::TryInto; + use ExprF::*; + match self.0.as_ref().as_ref() { + NaturalLit(n) => match (*n).try_into() { + Ok(n64) => visitor.visit_u64(n64), + Err(_) => match (*n).try_into() { + Ok(n32) => visitor.visit_u32(n32), + Err(_) => unimplemented!(), + }, + }, + IntegerLit(n) => match (*n).try_into() { + Ok(n64) => visitor.visit_i64(n64), + Err(_) => match (*n).try_into() { + Ok(n32) => visitor.visit_i32(n32), + Err(_) => unimplemented!(), + }, + }, + RecordLit(m) => visitor.visit_map( + serde::de::value::MapDeserializer::new(m.iter().map( + |(k, v)| (k.as_ref(), Deserializer(Cow::Borrowed(v))), + )), + ), + _ => unimplemented!(), + } + } + + serde::forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} diff --git a/dhall/src/api/traits/deserialize.rs b/dhall/src/api/traits/deserialize.rs new file mode 100644 index 0000000..9673cf9 --- /dev/null +++ b/dhall/src/api/traits/deserialize.rs @@ -0,0 +1,53 @@ +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/dynamic_type.rs b/dhall/src/api/traits/dynamic_type.rs new file mode 100644 index 0000000..7763a28 --- /dev/null +++ b/dhall/src/api/traits/dynamic_type.rs @@ -0,0 +1,32 @@ +use crate::error::TypeError; +use crate::phase::{Normalized, Type, Typed}; +use crate::traits::StaticType; +use std::borrow::Cow; + +pub trait DynamicType { + fn get_type<'a>(&'a self) -> Result, TypeError>; +} + +impl DynamicType for T { + fn get_type<'a>(&'a self) -> Result, TypeError> { + Ok(Cow::Owned(T::get_static_type())) + } +} + +impl DynamicType for Type { + fn get_type(&self) -> Result, TypeError> { + self.get_type() + } +} + +impl DynamicType for Normalized { + fn get_type(&self) -> Result, TypeError> { + self.0.get_type() + } +} + +impl DynamicType for Typed { + fn get_type(&self) -> Result, TypeError> { + self.get_type() + } +} diff --git a/dhall/src/api/traits/mod.rs b/dhall/src/api/traits/mod.rs new file mode 100644 index 0000000..315e17a --- /dev/null +++ b/dhall/src/api/traits/mod.rs @@ -0,0 +1,6 @@ +mod deserialize; +mod dynamic_type; +mod static_type; +pub use deserialize::Deserialize; +pub use dynamic_type::DynamicType; +pub use static_type::{SimpleStaticType, StaticType}; diff --git a/dhall/src/api/traits/static_type.rs b/dhall/src/api/traits/static_type.rs new file mode 100644 index 0000000..8b141a0 --- /dev/null +++ b/dhall/src/api/traits/static_type.rs @@ -0,0 +1,149 @@ +use crate::phase::*; +use dhall_proc_macros as dhall; +use dhall_syntax::*; + +/// A value that has a statically-known Dhall type. +/// +/// This trait is strictly more general than [SimpleStaticType]. +/// The reason is that it allows an arbitrary [Type] to be returned +/// instead of just a [SimpleType]. +/// +/// For now the only interesting impl is [SimpleType] itself, who +/// has a statically-known type which is not itself a [SimpleType]. +pub trait StaticType { + fn get_static_type() -> Type; +} + +/// A Rust type that can be represented as a Dhall type. +/// +/// A typical example is `Option`, +/// represented by the dhall expression `Optional Bool`. +/// +/// This trait can and should be automatically derived. +/// +/// The representation needs to be independent of the value. +/// For this reason, something like `HashMap` cannot implement +/// [SimpleStaticType] because each different value would +/// have a different Dhall record type. +/// +/// The `Simple` in `SimpleStaticType` indicates that the returned type is +/// a [SimpleType]. +pub trait SimpleStaticType { + fn get_simple_static_type() -> SimpleType; +} + +fn mktype(x: SubExpr) -> SimpleType { + x.into() +} + +impl StaticType for T { + fn get_static_type() -> Type { + crate::phase::Normalized::from_thunk_and_type( + crate::phase::normalize::Thunk::from_normalized_expr( + T::get_simple_static_type().into(), + ), + Type::const_type(), + ) + .to_type() + } +} + +impl StaticType for SimpleType { + /// By definition, a [SimpleType] has type `Type`. + /// This returns the Dhall expression `Type` + fn get_static_type() -> Type { + Type::const_type() + } +} + +impl SimpleStaticType for bool { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Bool)) + } +} + +impl SimpleStaticType for Natural { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Natural)) + } +} + +impl SimpleStaticType for u32 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Natural)) + } +} + +impl SimpleStaticType for u64 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Natural)) + } +} + +impl SimpleStaticType for Integer { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Integer)) + } +} + +impl SimpleStaticType for i32 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Integer)) + } +} + +impl SimpleStaticType for i64 { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(Integer)) + } +} + +impl SimpleStaticType for String { + fn get_simple_static_type() -> SimpleType { + mktype(dhall::subexpr!(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::subexpr!({ _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::subexpr!(Optional t)) + } +} + +impl SimpleStaticType for Vec { + fn get_simple_static_type() -> SimpleType { + let t: SubExpr<_, _> = T::get_simple_static_type().into(); + mktype(dhall::subexpr!(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::subexpr!({})) + } +} + +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::subexpr!(< Ok: tt | Err: te>)) + } +} diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 9f9c315..989170a 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -123,43 +123,8 @@ #[macro_use] mod tests; +mod api; pub mod error; mod phase; -mod serde; -mod traits; - -/// Deserialization of Dhall expressions into Rust -pub mod de { - pub use crate::traits::{Deserialize, SimpleStaticType, StaticType}; - #[doc(hidden)] - pub use dhall_proc_macros::SimpleStaticType; - - /// Deserialize an instance of type T from a string of Dhall text. - /// - /// This will recursively resolve all imports in the expression, and - /// 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. - /// - /// 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) - } - - /// Deserialize an instance of type T from a string of Dhall text, - /// additionally checking that it matches the type of T. - /// - /// This will recursively resolve all imports in the expression, and - /// 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(&::get_static_type())) - } -} +pub use api::de; +pub(crate) use api::traits; diff --git a/dhall/src/serde.rs b/dhall/src/serde.rs deleted file mode 100644 index 93921ba..0000000 --- a/dhall/src/serde.rs +++ /dev/null @@ -1,69 +0,0 @@ -use crate::error::{Error, Result}; -use crate::phase::{Normalized, Type}; -use crate::traits::Deserialize; -use dhall_syntax::*; -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()))) - } -} - -struct Deserializer<'a>(Cow<'a, SubExpr>); - -impl serde::de::Error for Error { - fn custom(msg: T) -> Self - where - T: std::fmt::Display, - { - Error::Deserialize(msg.to_string()) - } -} - -impl<'de: 'a, 'a> serde::de::IntoDeserializer<'de, Error> for Deserializer<'a> { - type Deserializer = Deserializer<'a>; - fn into_deserializer(self) -> Self::Deserializer { - self - } -} - -impl<'de: 'a, 'a> serde::Deserializer<'de> for Deserializer<'a> { - type Error = Error; - fn deserialize_any(self, visitor: V) -> Result - where - V: serde::de::Visitor<'de>, - { - use std::convert::TryInto; - use ExprF::*; - match self.0.as_ref().as_ref() { - NaturalLit(n) => match (*n).try_into() { - Ok(n64) => visitor.visit_u64(n64), - Err(_) => match (*n).try_into() { - Ok(n32) => visitor.visit_u32(n32), - Err(_) => unimplemented!(), - }, - }, - IntegerLit(n) => match (*n).try_into() { - Ok(n64) => visitor.visit_i64(n64), - Err(_) => match (*n).try_into() { - Ok(n32) => visitor.visit_i32(n32), - Err(_) => unimplemented!(), - }, - }, - RecordLit(m) => visitor.visit_map( - serde::de::value::MapDeserializer::new(m.iter().map( - |(k, v)| (k.as_ref(), Deserializer(Cow::Borrowed(v))), - )), - ), - _ => unimplemented!(), - } - } - - serde::forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } -} diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs deleted file mode 100644 index 9673cf9..0000000 --- a/dhall/src/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/traits/dynamic_type.rs b/dhall/src/traits/dynamic_type.rs deleted file mode 100644 index 7763a28..0000000 --- a/dhall/src/traits/dynamic_type.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::error::TypeError; -use crate::phase::{Normalized, Type, Typed}; -use crate::traits::StaticType; -use std::borrow::Cow; - -pub trait DynamicType { - fn get_type<'a>(&'a self) -> Result, TypeError>; -} - -impl DynamicType for T { - fn get_type<'a>(&'a self) -> Result, TypeError> { - Ok(Cow::Owned(T::get_static_type())) - } -} - -impl DynamicType for Type { - fn get_type(&self) -> Result, TypeError> { - self.get_type() - } -} - -impl DynamicType for Normalized { - fn get_type(&self) -> Result, TypeError> { - self.0.get_type() - } -} - -impl DynamicType for Typed { - fn get_type(&self) -> Result, TypeError> { - self.get_type() - } -} diff --git a/dhall/src/traits/mod.rs b/dhall/src/traits/mod.rs deleted file mode 100644 index 315e17a..0000000 --- a/dhall/src/traits/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod deserialize; -mod dynamic_type; -mod static_type; -pub use deserialize::Deserialize; -pub use dynamic_type::DynamicType; -pub use static_type::{SimpleStaticType, StaticType}; diff --git a/dhall/src/traits/static_type.rs b/dhall/src/traits/static_type.rs deleted file mode 100644 index 8b141a0..0000000 --- a/dhall/src/traits/static_type.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::phase::*; -use dhall_proc_macros as dhall; -use dhall_syntax::*; - -/// A value that has a statically-known Dhall type. -/// -/// This trait is strictly more general than [SimpleStaticType]. -/// The reason is that it allows an arbitrary [Type] to be returned -/// instead of just a [SimpleType]. -/// -/// For now the only interesting impl is [SimpleType] itself, who -/// has a statically-known type which is not itself a [SimpleType]. -pub trait StaticType { - fn get_static_type() -> Type; -} - -/// A Rust type that can be represented as a Dhall type. -/// -/// A typical example is `Option`, -/// represented by the dhall expression `Optional Bool`. -/// -/// This trait can and should be automatically derived. -/// -/// The representation needs to be independent of the value. -/// For this reason, something like `HashMap` cannot implement -/// [SimpleStaticType] because each different value would -/// have a different Dhall record type. -/// -/// The `Simple` in `SimpleStaticType` indicates that the returned type is -/// a [SimpleType]. -pub trait SimpleStaticType { - fn get_simple_static_type() -> SimpleType; -} - -fn mktype(x: SubExpr) -> SimpleType { - x.into() -} - -impl StaticType for T { - fn get_static_type() -> Type { - crate::phase::Normalized::from_thunk_and_type( - crate::phase::normalize::Thunk::from_normalized_expr( - T::get_simple_static_type().into(), - ), - Type::const_type(), - ) - .to_type() - } -} - -impl StaticType for SimpleType { - /// By definition, a [SimpleType] has type `Type`. - /// This returns the Dhall expression `Type` - fn get_static_type() -> Type { - Type::const_type() - } -} - -impl SimpleStaticType for bool { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Bool)) - } -} - -impl SimpleStaticType for Natural { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Natural)) - } -} - -impl SimpleStaticType for u32 { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Natural)) - } -} - -impl SimpleStaticType for u64 { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Natural)) - } -} - -impl SimpleStaticType for Integer { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Integer)) - } -} - -impl SimpleStaticType for i32 { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Integer)) - } -} - -impl SimpleStaticType for i64 { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(Integer)) - } -} - -impl SimpleStaticType for String { - fn get_simple_static_type() -> SimpleType { - mktype(dhall::subexpr!(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::subexpr!({ _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::subexpr!(Optional t)) - } -} - -impl SimpleStaticType for Vec { - fn get_simple_static_type() -> SimpleType { - let t: SubExpr<_, _> = T::get_simple_static_type().into(); - mktype(dhall::subexpr!(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::subexpr!({})) - } -} - -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::subexpr!(< Ok: tt | Err: te>)) - } -} -- cgit v1.2.3