summaryrefslogtreecommitdiff
path: root/dhall
diff options
context:
space:
mode:
authorNadrieril2019-05-09 21:54:45 +0200
committerNadrieril2019-05-09 21:54:45 +0200
commitdae106b3de0888e8a704c0efa3f9d991590f7858 (patch)
tree750daf7cb5b44bed4772ace3457c583c0ef86e4d /dhall
parent6444faa2dee271e6d22226dc30b659e13fa8aead (diff)
Rewrite the StaticType trait and everything around it
Diffstat (limited to '')
-rw-r--r--dhall/src/api/mod.rs85
-rw-r--r--dhall/src/api/static_type.rs93
-rw-r--r--dhall/src/api/traits/dynamic_type.rs32
-rw-r--r--dhall/src/api/traits/mod.rs4
-rw-r--r--dhall/src/api/traits/static_type.rs149
-rw-r--r--dhall/src/lib.rs10
-rw-r--r--dhall/src/phase/mod.rs57
-rw-r--r--dhall/src/phase/typecheck.rs2
-rw-r--r--dhall/tests/traits.rs67
-rw-r--r--dhall_proc_macros/src/derive.rs66
-rw-r--r--dhall_proc_macros/src/lib.rs6
11 files changed, 257 insertions, 314 deletions
diff --git a/dhall/src/api/mod.rs b/dhall/src/api/mod.rs
index 0a0ef93..72789d9 100644
--- a/dhall/src/api/mod.rs
+++ b/dhall/src/api/mod.rs
@@ -1,13 +1,88 @@
mod serde;
+pub(crate) mod static_type;
pub(crate) mod traits;
+// pub struct Value(crate::phase::Normalized);
+
+pub use typ::Type;
+
+mod typ {
+ use crate::core::thunk::{Thunk, TypeThunk};
+ use crate::core::value::Value;
+ use crate::phase::{NormalizedSubExpr, Typed};
+ use dhall_syntax::Builtin;
+
+ /// A Dhall expression representing a type.
+ ///
+ /// This captures what is usually simply called a "type", like
+ /// `Bool`, `{ x: Integer }` or `Natural -> Text`.
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct Type(Typed);
+
+ impl Type {
+ pub(crate) fn from_value(v: Value) -> Self {
+ Type(Typed::from_value_untyped(v))
+ }
+ pub(crate) fn make_builtin_type(b: Builtin) -> Self {
+ Self::from_value(Value::from_builtin(b))
+ }
+ pub(crate) fn make_optional_type(t: Type) -> Self {
+ Self::from_value(Value::AppliedBuiltin(
+ Builtin::Optional,
+ vec![t.to_thunk()],
+ ))
+ }
+ pub(crate) fn make_list_type(t: Type) -> Self {
+ Self::from_value(Value::AppliedBuiltin(
+ Builtin::List,
+ vec![t.to_thunk()],
+ ))
+ }
+ #[doc(hidden)]
+ pub fn from_normalized_expr(e: NormalizedSubExpr) -> Self {
+ Type(Typed::from_normalized_expr_untyped(e))
+ }
+ #[doc(hidden)]
+ pub fn make_record_type(
+ kts: impl Iterator<Item = (String, Type)>,
+ ) -> Self {
+ Self::from_value(Value::RecordType(
+ kts.map(|(k, t)| {
+ (k.into(), TypeThunk::from_thunk(t.to_thunk()))
+ })
+ .collect(),
+ ))
+ }
+ #[doc(hidden)]
+ pub fn make_union_type(
+ kts: impl Iterator<Item = (String, Option<Type>)>,
+ ) -> Self {
+ Self::from_value(Value::UnionType(
+ kts.map(|(k, t)| {
+ (k.into(), t.map(|t| TypeThunk::from_thunk(t.to_thunk())))
+ })
+ .collect(),
+ ))
+ }
+
+ pub(crate) fn to_thunk(&self) -> Thunk {
+ self.0.to_thunk()
+ }
+ #[allow(dead_code)]
+ pub(crate) fn to_expr(&self) -> NormalizedSubExpr {
+ self.0.to_expr()
+ }
+ }
+}
+
/// Deserialization of Dhall expressions into Rust
pub mod de {
+ pub use super::static_type::StaticType;
+ pub use super::Type;
#[doc(hidden)]
- pub use crate::phase::SimpleType;
- pub use crate::traits::{Deserialize, SimpleStaticType, StaticType};
+ pub use crate::traits::Deserialize;
#[doc(hidden)]
- pub use dhall_proc_macros::SimpleStaticType;
+ pub use dhall_proc_macros::StaticType;
/// Deserialize an instance of type T from a string of Dhall text.
///
@@ -35,6 +110,8 @@ pub mod de {
pub fn from_str_auto_type<'a, T: Deserialize<'a> + StaticType>(
s: &'a str,
) -> crate::error::Result<T> {
- from_str(s, Some(&<T as StaticType>::get_static_type()))
+ // from_str(s, Some(&<T as StaticType>::static_type()))
+ // TODO
+ from_str(s, None)
}
}
diff --git a/dhall/src/api/static_type.rs b/dhall/src/api/static_type.rs
new file mode 100644
index 0000000..906bcef
--- /dev/null
+++ b/dhall/src/api/static_type.rs
@@ -0,0 +1,93 @@
+use dhall_syntax::{Builtin, Integer, Natural};
+
+use crate::api::Type;
+
+/// A Rust type that can be represented as a Dhall type.
+///
+/// A typical example is `Option<bool>`,
+/// 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<String, bool>` cannot implement
+/// [StaticType] because each different value would
+/// have a different Dhall record type.
+pub trait StaticType {
+ fn static_type() -> Type;
+}
+
+macro_rules! derive_builtin {
+ ($ty:ty, $builtin:ident) => {
+ impl StaticType for $ty {
+ fn static_type() -> Type {
+ Type::make_builtin_type(Builtin::$builtin)
+ }
+ }
+ };
+}
+
+derive_builtin!(bool, Bool);
+derive_builtin!(Natural, Natural);
+derive_builtin!(u64, Natural);
+derive_builtin!(Integer, Integer);
+derive_builtin!(String, Text);
+
+impl<A, B> StaticType for (A, B)
+where
+ A: StaticType,
+ B: StaticType,
+{
+ fn static_type() -> Type {
+ Type::make_record_type(
+ vec![
+ ("_1".to_owned(), A::static_type()),
+ ("_2".to_owned(), B::static_type()),
+ ]
+ .into_iter(),
+ )
+ }
+}
+
+impl<T, E> StaticType for std::result::Result<T, E>
+where
+ T: StaticType,
+ E: StaticType,
+{
+ fn static_type() -> Type {
+ Type::make_union_type(
+ vec![
+ ("Ok".to_owned(), Some(T::static_type())),
+ ("Err".to_owned(), Some(E::static_type())),
+ ]
+ .into_iter(),
+ )
+ }
+}
+
+impl<T> StaticType for Option<T>
+where
+ T: StaticType,
+{
+ fn static_type() -> Type {
+ Type::make_optional_type(T::static_type())
+ }
+}
+
+impl<T> StaticType for Vec<T>
+where
+ T: StaticType,
+{
+ fn static_type() -> Type {
+ Type::make_list_type(T::static_type())
+ }
+}
+
+impl<'a, T> StaticType for &'a T
+where
+ T: StaticType,
+{
+ fn static_type() -> Type {
+ T::static_type()
+ }
+}
diff --git a/dhall/src/api/traits/dynamic_type.rs b/dhall/src/api/traits/dynamic_type.rs
deleted file mode 100644
index 7763a28..0000000
--- a/dhall/src/api/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<Cow<'a, Type>, TypeError>;
-}
-
-impl<T: StaticType> DynamicType for T {
- fn get_type<'a>(&'a self) -> Result<Cow<'a, Type>, TypeError> {
- Ok(Cow::Owned(T::get_static_type()))
- }
-}
-
-impl DynamicType for Type {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
- self.get_type()
- }
-}
-
-impl DynamicType for Normalized {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
- self.0.get_type()
- }
-}
-
-impl DynamicType for Typed {
- fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
- self.get_type()
- }
-}
diff --git a/dhall/src/api/traits/mod.rs b/dhall/src/api/traits/mod.rs
index 315e17a..3fd21e4 100644
--- a/dhall/src/api/traits/mod.rs
+++ b/dhall/src/api/traits/mod.rs
@@ -1,6 +1,2 @@
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
deleted file mode 100644
index e05dfff..0000000
--- a/dhall/src/api/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<bool>`,
-/// 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<String, bool>` 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<X, X>) -> SimpleType {
- x.into()
-}
-
-impl<T: SimpleStaticType> StaticType for T {
- fn get_static_type() -> Type {
- crate::phase::Normalized::from_thunk_and_type(
- crate::core::thunk::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<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::subexpr!({ _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::subexpr!(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::subexpr!(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::subexpr!({}))
- }
-}
-
-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::subexpr!(< Ok: tt | Err: te>))
- }
-}
diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs
index b35b2ae..c25fc82 100644
--- a/dhall/src/lib.rs
+++ b/dhall/src/lib.rs
@@ -35,15 +35,15 @@
//! ### Custom datatype
//!
//! If you have a custom datatype for which you derived [serde::Deserialize], chances are
-//! you will be able to derive [SimpleStaticType][de::SimpleStaticType] for it as well.
+//! you will be able to derive [StaticType][de::StaticType] for it as well.
//! This gives you access to a dhall representation of your datatype that can be outputted
//! to users, and allows easy type-safe deserializing.
//!
//! ```edition2018
//! use serde::Deserialize;
-//! use dhall::de::SimpleStaticType;
+//! use dhall::de::StaticType;
//!
-//! #[derive(Debug, Deserialize, SimpleStaticType)]
+//! #[derive(Debug, Deserialize, StaticType)]
//! struct Point {
//! x: u64,
//! y: u64,
@@ -68,7 +68,7 @@
//! If you used to consume JSON or YAML in a loosely typed way, you can continue to do so
//! with dhall. You only need to replace [serde_json::from_str] or [serde_yaml::from_str]
//! with [dhall::de::from_str][de::from_str].
-//! More generally, if the [SimpleStaticType][de::SimpleStaticType] derive doesn't suit your
+//! More generally, if the [StaticType][de::StaticType] derive doesn't suit your
//! needs, you can still deserialize any valid dhall file that serde can handle.
//!
//! [serde_json::from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
@@ -130,4 +130,4 @@ pub mod error;
pub(crate) mod phase;
pub(crate) use api::traits;
-pub use api::de;
+pub use api::*;
diff --git a/dhall/src/phase/mod.rs b/dhall/src/phase/mod.rs
index af39eb6..5262a27 100644
--- a/dhall/src/phase/mod.rs
+++ b/dhall/src/phase/mod.rs
@@ -49,19 +49,6 @@ pub(crate) enum Typed {
#[derive(Debug, Clone)]
pub(crate) struct Normalized(pub(crate) Typed);
-/// A Dhall expression representing a simple type.
-///
-/// This captures what is usually simply called a "type", like
-/// `Bool`, `{ x: Integer }` or `Natural -> Text`.
-///
-/// For a more general notion of "type", see [Type].
-#[derive(Debug, Clone)]
-pub struct SimpleType(pub(crate) NormalizedSubExpr);
-
-/// A Dhall expression representing a (possibly higher-kinded) type.
-///
-/// This includes [SimpleType]s but also higher-kinded expressions like
-/// `Type`, `Kind` and `{ x: Type }`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Type(pub(crate) Typed);
@@ -131,6 +118,12 @@ impl Typed {
pub(crate) fn from_const(c: Const) -> Self {
Typed::Const(c)
}
+ pub(crate) fn from_value_untyped(v: Value) -> Self {
+ Typed::Untyped(Thunk::from_value(v))
+ }
+ pub(crate) fn from_normalized_expr_untyped(e: NormalizedSubExpr) -> Self {
+ Typed::from_thunk_untyped(Thunk::from_normalized_expr(e))
+ }
// TODO: Avoid cloning if possible
pub(crate) fn to_value(&self) -> Value {
@@ -179,6 +172,7 @@ impl Typed {
}
impl Type {
+ // Deprecated
pub(crate) fn to_normalized(&self) -> Normalized {
self.0.clone().normalize()
}
@@ -202,19 +196,12 @@ impl Type {
self.0.get_type()
}
- pub(crate) fn const_type() -> Self {
- Type::from_const(Const::Type)
- }
pub(crate) fn from_const(c: Const) -> Self {
Type(Typed::from_const(c))
}
}
impl Normalized {
- pub(crate) fn from_thunk_and_type(th: Thunk, t: Type) -> Self {
- Normalized(Typed::from_thunk_and_type(th, t))
- }
-
pub(crate) fn to_expr(&self) -> NormalizedSubExpr {
self.0.to_expr()
}
@@ -225,9 +212,12 @@ impl Normalized {
pub(crate) fn to_value(&self) -> Value {
self.0.to_value()
}
- pub(crate) fn to_type(self) -> Type {
+ pub(crate) fn to_type(&self) -> Type {
self.0.to_type()
}
+ pub(crate) fn into_typed(self) -> Typed {
+ self.0
+ }
pub(crate) fn get_type(&self) -> Result<Cow<'_, Type>, TypeError> {
self.0.get_type()
}
@@ -301,7 +291,6 @@ macro_rules! derive_traits_for_wrapper_struct {
derive_traits_for_wrapper_struct!(Parsed);
derive_traits_for_wrapper_struct!(Resolved);
derive_traits_for_wrapper_struct!(Normalized);
-derive_traits_for_wrapper_struct!(SimpleType);
impl Eq for Typed {}
impl PartialEq for Typed {
@@ -321,27 +310,3 @@ impl Display for Type {
self.to_normalized().fmt(f)
}
}
-
-// Exposed for the macros
-#[doc(hidden)]
-impl From<SimpleType> for NormalizedSubExpr {
- fn from(x: SimpleType) -> NormalizedSubExpr {
- x.0
- }
-}
-
-// Exposed for the macros
-#[doc(hidden)]
-impl From<NormalizedSubExpr> for SimpleType {
- fn from(x: NormalizedSubExpr) -> SimpleType {
- SimpleType(x)
- }
-}
-
-// Exposed for the macros
-#[doc(hidden)]
-impl From<Normalized> for Typed {
- fn from(x: Normalized) -> Typed {
- x.0
- }
-}
diff --git a/dhall/src/phase/typecheck.rs b/dhall/src/phase/typecheck.rs
index e1dffb0..7f988c8 100644
--- a/dhall/src/phase/typecheck.rs
+++ b/dhall/src/phase/typecheck.rs
@@ -391,7 +391,7 @@ fn type_with(
let e = e.rewrap(Annot(x, t));
return type_with(ctx, e);
}
- Embed(p) => p.clone().into(),
+ Embed(p) => p.clone().into_typed(),
Var(var) => match ctx.lookup(&var) {
Some(typed) => typed,
None => {
diff --git a/dhall/tests/traits.rs b/dhall/tests/traits.rs
index 65220dc..75eaf75 100644
--- a/dhall/tests/traits.rs
+++ b/dhall/tests/traits.rs
@@ -1,79 +1,76 @@
#![feature(proc_macro_hygiene)]
-use dhall::de::SimpleStaticType;
-use dhall_proc_macros;
+use dhall::de::{StaticType, Type};
+use dhall_proc_macros::subexpr;
use dhall_syntax::{SubExpr, X};
#[test]
fn test_static_type() {
- fn mktype(x: SubExpr<X, X>) -> dhall::de::SimpleType {
- x.into()
+ fn mktype(x: SubExpr<X, X>) -> Type {
+ Type::from_normalized_expr(x)
}
+ assert_eq!(bool::static_type(), mktype(subexpr!(Bool)));
+ assert_eq!(String::static_type(), mktype(subexpr!(Text)));
assert_eq!(
- bool::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!(Bool))
+ <Option<bool>>::static_type(),
+ mktype(subexpr!(Optional Bool))
);
assert_eq!(
- String::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!(Text))
- );
- assert_eq!(
- <Option<bool>>::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!(Optional Bool))
- );
- assert_eq!(
- <(bool, Option<String>)>::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!({ _1: Bool, _2: Optional Text }))
+ <(bool, Vec<String>)>::static_type(),
+ mktype(subexpr!({ _1: Bool, _2: List Text }))
);
- #[derive(dhall::de::SimpleStaticType)]
+ #[derive(dhall::de::StaticType)]
#[allow(dead_code)]
struct A {
field1: bool,
field2: Option<bool>,
}
assert_eq!(
- <A as dhall::de::SimpleStaticType>::get_simple_static_type(),
- mktype(
- dhall_proc_macros::subexpr!({ field1: Bool, field2: Optional Bool })
- )
+ <A as dhall::de::StaticType>::static_type(),
+ mktype(subexpr!({ field1: Bool, field2: Optional Bool }))
);
- #[derive(SimpleStaticType)]
+ #[derive(StaticType)]
#[allow(dead_code)]
struct B<'a, T: 'a> {
field1: &'a T,
field2: Option<T>,
}
- assert_eq!(
- <B<'static, bool>>::get_simple_static_type(),
- A::get_simple_static_type()
- );
+ assert_eq!(<B<'static, bool>>::static_type(), A::static_type());
- #[derive(SimpleStaticType)]
+ #[derive(StaticType)]
#[allow(dead_code)]
struct C<T>(T, Option<String>);
assert_eq!(
- <C<bool>>::get_simple_static_type(),
- <(bool, Option<String>)>::get_simple_static_type()
+ <C<bool>>::static_type(),
+ <(bool, Option<String>)>::static_type()
);
- #[derive(SimpleStaticType)]
+ #[derive(StaticType)]
#[allow(dead_code)]
struct D();
assert_eq!(
- <C<D>>::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!({ _1: {}, _2: Optional Text }))
+ <C<D>>::static_type(),
+ mktype(subexpr!({ _1: {}, _2: Optional Text }))
);
- #[derive(SimpleStaticType)]
+ #[derive(StaticType)]
#[allow(dead_code)]
enum E<T> {
A(T),
B(String),
};
assert_eq!(
- <E<bool>>::get_simple_static_type(),
- mktype(dhall_proc_macros::subexpr!(< A: Bool | B: Text >))
+ <E<bool>>::static_type(),
+ mktype(subexpr!(< A: Bool | B: Text >))
);
+
+ #[derive(StaticType)]
+ #[allow(dead_code)]
+ enum F {
+ A,
+ B(bool),
+ };
+ assert_eq!(F::static_type(), mktype(subexpr!(< A | B: Bool >)));
}
diff --git a/dhall_proc_macros/src/derive.rs b/dhall_proc_macros/src/derive.rs
index a5f0925..725cdfb 100644
--- a/dhall_proc_macros/src/derive.rs
+++ b/dhall_proc_macros/src/derive.rs
@@ -6,19 +6,19 @@ use syn::spanned::Spanned;
use syn::Error;
use syn::{parse_quote, DeriveInput};
-pub fn derive_simple_static_type(input: TokenStream) -> TokenStream {
- TokenStream::from(match derive_simple_static_type_inner(input) {
+pub fn derive_static_type(input: TokenStream) -> TokenStream {
+ TokenStream::from(match derive_static_type_inner(input) {
Ok(tokens) => tokens,
Err(err) => err.to_compile_error(),
})
}
-fn get_simple_static_type<T>(ty: T) -> proc_macro2::TokenStream
+fn static_type<T>(ty: T) -> proc_macro2::TokenStream
where
T: quote::ToTokens,
{
quote!(
- <#ty as ::dhall::de::SimpleStaticType>::get_simple_static_type()
+ <#ty as ::dhall::de::StaticType>::static_type()
)
}
@@ -48,39 +48,35 @@ fn derive_for_struct(
.collect(),
syn::Fields::Unit => vec![],
};
- let fields = fields
- .into_iter()
- .map(|(name, ty)| {
- let name = dhall_syntax::Label::from(name);
- constraints.push(ty.clone());
- let ty = get_simple_static_type(ty);
- (name, quote!(#ty.into()))
- })
- .collect();
- let record =
- crate::quote::quote_exprf(dhall_syntax::ExprF::RecordType(fields));
- Ok(quote! { dhall_syntax::rc(#record) })
+ let entries = fields.into_iter().map(|(name, ty)| {
+ constraints.push(ty.clone());
+ let ty = static_type(ty);
+ quote!( (#name.to_owned(), #ty) )
+ });
+ Ok(quote! { ::dhall::de::Type::make_record_type(
+ vec![ #(#entries),* ].into_iter()
+ ) })
}
fn derive_for_enum(
data: &syn::DataEnum,
constraints: &mut Vec<syn::Type>,
) -> Result<proc_macro2::TokenStream, Error> {
- let variants = data
+ let entries: Vec<_> = data
.variants
.iter()
.map(|v| {
- let name = dhall_syntax::Label::from(v.ident.to_string());
+ let name = v.ident.to_string();
match &v.fields {
- syn::Fields::Unit => Ok((name, None)),
+ syn::Fields::Unit => Ok(quote!( (#name.to_owned(), None) )),
syn::Fields::Unnamed(fields) if fields.unnamed.is_empty() => {
- Ok((name, None))
+ Ok(quote!( (#name.to_owned(), None) ))
}
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
let ty = &fields.unnamed.iter().next().unwrap().ty;
constraints.push(ty.clone());
- let ty = get_simple_static_type(ty);
- Ok((name, Some(quote!(#ty.into()))))
+ let ty = static_type(ty);
+ Ok(quote!( (#name.to_owned(), Some(#ty)) ))
}
syn::Fields::Unnamed(_) => Err(Error::new(
v.span(),
@@ -94,17 +90,17 @@ fn derive_for_enum(
})
.collect::<Result<_, Error>>()?;
- let union =
- crate::quote::quote_exprf(dhall_syntax::ExprF::UnionType(variants));
- Ok(quote! { dhall_syntax::rc(#union) })
+ Ok(quote! { ::dhall::de::Type::make_union_type(
+ vec![ #(#entries),* ].into_iter()
+ ) })
}
-pub fn derive_simple_static_type_inner(
+pub fn derive_static_type_inner(
input: TokenStream,
) -> Result<proc_macro2::TokenStream, Error> {
let input: DeriveInput = syn::parse_macro_input::parse(input)?;
- // List of types that must impl Type
+ // List of types that must impl StaticType
let mut constraints = vec![];
let get_type = match &input.data {
@@ -132,13 +128,13 @@ pub fn derive_simple_static_type_inner(
// Hygienic errors
let assertions = constraints.iter().enumerate().map(|(i, ty)| {
- // Ensure that ty: Type, with an appropriate span
+ // Ensure that ty: StaticType, with an appropriate span
let assert_name =
syn::Ident::new(&format!("_AssertType{}", i), ty.span());
let mut local_where_clause = orig_where_clause.clone();
local_where_clause
.predicates
- .push(parse_quote!(#ty: ::dhall::de::SimpleStaticType));
+ .push(parse_quote!(#ty: ::dhall::de::StaticType));
let phantoms = generics.params.iter().map(|param| match param {
syn::GenericParam::Type(syn::TypeParam { ident, .. }) => {
quote!(#ident)
@@ -155,23 +151,23 @@ pub fn derive_simple_static_type_inner(
}
});
- // Ensure that all the fields have a Type impl
+ // Ensure that all the fields have a StaticType impl
let mut where_clause = orig_where_clause.clone();
for ty in constraints.iter() {
where_clause
.predicates
- .push(parse_quote!(#ty: ::dhall::de::SimpleStaticType));
+ .push(parse_quote!(#ty: ::dhall::de::StaticType));
}
let ident = &input.ident;
let tokens = quote! {
- impl #impl_generics ::dhall::de::SimpleStaticType
+ impl #impl_generics ::dhall::de::StaticType
for #ident #ty_generics
#where_clause {
- fn get_simple_static_type() ->
- ::dhall::de::SimpleType {
+ fn static_type() ->
+ ::dhall::de::Type {
#(#assertions)*
- ::dhall::de::SimpleType::from(#get_type)
+ #get_type
}
}
};
diff --git a/dhall_proc_macros/src/lib.rs b/dhall_proc_macros/src/lib.rs
index 1124968..e4aa8b5 100644
--- a/dhall_proc_macros/src/lib.rs
+++ b/dhall_proc_macros/src/lib.rs
@@ -20,7 +20,7 @@ pub fn subexpr(input: TokenStream) -> TokenStream {
quote::subexpr(input)
}
-#[proc_macro_derive(SimpleStaticType)]
-pub fn derive_simple_static_type(input: TokenStream) -> TokenStream {
- derive::derive_simple_static_type(input)
+#[proc_macro_derive(StaticType)]
+pub fn derive_static_type(input: TokenStream) -> TokenStream {
+ derive::derive_static_type(input)
}