summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2020-03-08 17:36:51 +0000
committerNadrieril2020-03-31 21:44:01 +0100
commit4e11e882b7d064e9ddf997f9a465206cf6e471aa (patch)
tree17cba8f042c0ca9c8b863839d9244b25aa9b7fe0
parent84796fd247eb1a13fcd092a7cd7ec2d587b261bd (diff)
Split serde_dhall::Value to separate values from types
-rw-r--r--README.md4
-rw-r--r--dhall_proc_macros/src/derive.rs6
-rw-r--r--serde_dhall/src/lib.rs86
-rw-r--r--serde_dhall/src/static_type.rs26
-rw-r--r--serde_dhall/tests/traits.rs4
-rw-r--r--test.dhall4
6 files changed, 88 insertions, 42 deletions
diff --git a/README.md b/README.md
index ffd55ef..1bcf558 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,10 @@ same name as the corresponding test.
## Changelog
+#### [???]
+
+- Breaking change: use `serde_dhall::Type` type for type-checking instead of `serde_dhall::Value`
+
#### [0.4.0]
- `dhall` now uses the stable Rust toolchain !
diff --git a/dhall_proc_macros/src/derive.rs b/dhall_proc_macros/src/derive.rs
index 48626a0..3a4f1aa 100644
--- a/dhall_proc_macros/src/derive.rs
+++ b/dhall_proc_macros/src/derive.rs
@@ -52,7 +52,7 @@ fn derive_for_struct(
let ty = static_type(ty);
quote!( (#name.to_owned(), #ty) )
});
- Ok(quote! { ::serde_dhall::value::Value::make_record_type(
+ Ok(quote! { ::serde_dhall::Type::make_record_type(
vec![ #(#entries),* ].into_iter()
) })
}
@@ -89,7 +89,7 @@ fn derive_for_enum(
})
.collect::<Result<_, Error>>()?;
- Ok(quote! { ::serde_dhall::value::Value::make_union_type(
+ Ok(quote! { ::serde_dhall::Type::make_union_type(
vec![ #(#entries),* ].into_iter()
) })
}
@@ -165,7 +165,7 @@ pub fn derive_static_type_inner(
for #ident #ty_generics
#where_clause {
fn static_type() ->
- ::serde_dhall::value::Value {
+ ::serde_dhall::Type {
#(#assertions)*
#get_type
}
diff --git a/serde_dhall/src/lib.rs b/serde_dhall/src/lib.rs
index 55e098c..5f386e3 100644
--- a/serde_dhall/src/lib.rs
+++ b/serde_dhall/src/lib.rs
@@ -106,17 +106,17 @@
//! There are two ways to typecheck a Dhall value: you can provide the type as Dhall text or you
//! can let Rust infer it for you.
//!
-//! To provide a type written in Dhall, first parse it into a [`serde_dhall::Value`][Value], then
+//! To provide a type written in Dhall, first parse it into a [`serde_dhall::Type`][Type], then
//! pass it to [`from_str_check_type`][from_str_check_type].
//!
//! ```rust
//! # fn main() -> serde_dhall::de::Result<()> {
-//! use serde_dhall::Value;
+//! use serde_dhall::Type;
//! use std::collections::HashMap;
//!
//! // Parse a Dhall type
//! let point_type_str = "{ x: Natural, y: Natural }";
-//! let point_type: Value = serde_dhall::from_str(point_type_str)?;
+//! let point_type: Type = serde_dhall::from_str(point_type_str)?;
//!
//! // Some Dhall data
//! let point_data = "{ x = 1, y = 1 + 1 }";
@@ -176,30 +176,29 @@ pub use de::{from_str, from_str_auto_type, from_str_check_type};
pub use dhall_proc_macros::StaticType;
pub use static_type::StaticType;
#[doc(inline)]
+pub use ty::Type;
+#[doc(inline)]
pub use value::Value;
// A Dhall value.
#[doc(hidden)]
pub mod value {
- use dhall::syntax::Builtin;
use dhall::{Normalized, NormalizedExpr, Parsed, SimpleValue};
use super::de::Error;
+ use super::Type;
/// A Dhall value
#[derive(Debug, Clone, PartialEq, Eq)]
- pub struct Value(Normalized);
+ pub struct Value(pub(crate) Normalized);
impl Value {
- pub fn from_str(
- s: &str,
- ty: Option<&Value>,
- ) -> super::de::Result<Self> {
+ pub fn from_str(s: &str, ty: Option<&Type>) -> super::de::Result<Self> {
Value::from_str_using_dhall_error_type(s, ty).map_err(Error::Dhall)
}
fn from_str_using_dhall_error_type(
s: &str,
- ty: Option<&Value>,
+ ty: Option<&Type>,
) -> dhall::error::Result<Self> {
let resolved = Parsed::parse_str(s)?.resolve()?;
let typed = match ty {
@@ -213,41 +212,79 @@ pub mod value {
) -> Result<SimpleValue, NormalizedExpr> {
self.0.to_simple_value()
}
+ }
+
+ impl super::de::sealed::Sealed for Value {}
+
+ impl super::de::Deserialize for Value {
+ fn from_dhall(v: &Value) -> super::de::Result<Self> {
+ Ok(v.clone())
+ }
+ }
+}
+
+// A Dhall type.
+#[doc(hidden)]
+pub mod ty {
+ use dhall::syntax::Builtin;
+ use dhall::{Normalized, Parsed};
+
+ use super::de::Error;
+
+ /// A Dhall value
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct Type(Normalized);
+
+ impl Type {
+ pub fn from_str(s: &str, ty: Option<&Type>) -> super::de::Result<Self> {
+ Type::from_str_using_dhall_error_type(s, ty).map_err(Error::Dhall)
+ }
+ fn from_str_using_dhall_error_type(
+ s: &str,
+ ty: Option<&Type>,
+ ) -> dhall::error::Result<Self> {
+ let resolved = Parsed::parse_str(s)?.resolve()?;
+ let typed = match ty {
+ None => resolved.typecheck()?,
+ Some(t) => resolved.typecheck_with(t.as_normalized())?,
+ };
+ Ok(Type(typed.normalize()))
+ }
pub(crate) fn as_normalized(&self) -> &Normalized {
&self.0
}
pub(crate) fn make_builtin_type(b: Builtin) -> Self {
- Value(Normalized::make_builtin_type(b))
+ Type(Normalized::make_builtin_type(b))
}
- pub(crate) fn make_optional_type(t: Value) -> Self {
- Value(Normalized::make_optional_type(t.0))
+ pub(crate) fn make_optional_type(t: Type) -> Self {
+ Type(Normalized::make_optional_type(t.0))
}
- pub(crate) fn make_list_type(t: Value) -> Self {
- Value(Normalized::make_list_type(t.0))
+ pub(crate) fn make_list_type(t: Type) -> Self {
+ Type(Normalized::make_list_type(t.0))
}
// Made public for the StaticType derive macro
#[doc(hidden)]
pub fn make_record_type(
- kts: impl Iterator<Item = (String, Value)>,
+ kts: impl Iterator<Item = (String, Type)>,
) -> Self {
- Value(Normalized::make_record_type(kts.map(|(k, t)| (k, t.0))))
+ Type(Normalized::make_record_type(kts.map(|(k, t)| (k, t.0))))
}
#[doc(hidden)]
pub fn make_union_type(
- kts: impl Iterator<Item = (String, Option<Value>)>,
+ kts: impl Iterator<Item = (String, Option<Type>)>,
) -> Self {
- Value(Normalized::make_union_type(
+ Type(Normalized::make_union_type(
kts.map(|(k, t)| (k, t.map(|t| t.0))),
))
}
}
- impl super::de::sealed::Sealed for Value {}
+ impl super::de::sealed::Sealed for Type {}
- impl super::de::Deserialize for Value {
- fn from_dhall(v: &Value) -> super::de::Result<Self> {
- Ok(v.clone())
+ impl super::de::Deserialize for Type {
+ fn from_dhall(v: &super::Value) -> super::de::Result<Self> {
+ Ok(Type(v.0.clone()))
}
}
}
@@ -255,6 +292,7 @@ pub mod value {
/// Deserialize Dhall data to a Rust data structure.
pub mod de {
use super::StaticType;
+ use super::Type;
use super::Value;
pub use error::{Error, Result};
@@ -324,7 +362,7 @@ pub mod de {
///
/// Like [from_str], but this additionally checks that
/// the type of the provided expression matches the supplied type.
- pub fn from_str_check_type<T>(s: &str, ty: &Value) -> Result<T>
+ pub fn from_str_check_type<T>(s: &str, ty: &Type) -> Result<T>
where
T: Deserialize,
{
diff --git a/serde_dhall/src/static_type.rs b/serde_dhall/src/static_type.rs
index 1eb9150..921b296 100644
--- a/serde_dhall/src/static_type.rs
+++ b/serde_dhall/src/static_type.rs
@@ -1,6 +1,6 @@
use dhall::syntax::Builtin;
-use crate::Value;
+use crate::Type;
/// A Rust type that can be represented as a Dhall type.
///
@@ -14,14 +14,14 @@ use crate::Value;
/// [StaticType] because each different value would
/// have a different Dhall record type.
pub trait StaticType {
- fn static_type() -> Value;
+ fn static_type() -> Type;
}
macro_rules! derive_builtin {
($ty:ty, $builtin:ident) => {
impl StaticType for $ty {
- fn static_type() -> Value {
- Value::make_builtin_type(Builtin::$builtin)
+ fn static_type() -> Type {
+ Type::make_builtin_type(Builtin::$builtin)
}
}
};
@@ -43,8 +43,8 @@ where
A: StaticType,
B: StaticType,
{
- fn static_type() -> Value {
- Value::make_record_type(
+ fn static_type() -> Type {
+ Type::make_record_type(
vec![
("_1".to_owned(), A::static_type()),
("_2".to_owned(), B::static_type()),
@@ -59,8 +59,8 @@ where
T: StaticType,
E: StaticType,
{
- fn static_type() -> Value {
- Value::make_union_type(
+ fn static_type() -> Type {
+ Type::make_union_type(
vec![
("Ok".to_owned(), Some(T::static_type())),
("Err".to_owned(), Some(E::static_type())),
@@ -74,8 +74,8 @@ impl<T> StaticType for Option<T>
where
T: StaticType,
{
- fn static_type() -> Value {
- Value::make_optional_type(T::static_type())
+ fn static_type() -> Type {
+ Type::make_optional_type(T::static_type())
}
}
@@ -83,8 +83,8 @@ impl<T> StaticType for Vec<T>
where
T: StaticType,
{
- fn static_type() -> Value {
- Value::make_list_type(T::static_type())
+ fn static_type() -> Type {
+ Type::make_list_type(T::static_type())
}
}
@@ -92,7 +92,7 @@ impl<'a, T> StaticType for &'a T
where
T: StaticType,
{
- fn static_type() -> Value {
+ fn static_type() -> Type {
T::static_type()
}
}
diff --git a/serde_dhall/tests/traits.rs b/serde_dhall/tests/traits.rs
index 15a91ed..b2fe6e5 100644
--- a/serde_dhall/tests/traits.rs
+++ b/serde_dhall/tests/traits.rs
@@ -1,8 +1,8 @@
-use serde_dhall::{from_str, StaticType, Value};
+use serde_dhall::{from_str, StaticType, Type};
#[test]
fn test_static_type() {
- fn parse(s: &str) -> Value {
+ fn parse(s: &str) -> Type {
from_str(s).unwrap()
}
diff --git a/test.dhall b/test.dhall
new file mode 100644
index 0000000..641c219
--- /dev/null
+++ b/test.dhall
@@ -0,0 +1,4 @@
+let Prelude =
+ https://prelude.dhall-lang.org/package.dhall sha256:c1b3fc613aabfb64a9e17f6c0d70fe82016a030beedd79851730993e9083fde2
+
+in Prelude