summaryrefslogtreecommitdiff
path: root/dhall/src/api
diff options
context:
space:
mode:
authorFintan Halpenny2019-09-02 23:09:26 +0100
committerFintan Halpenny2019-09-02 23:09:26 +0100
commit8553b398a5f97eed240f5360282e911392cab6ff (patch)
tree076d554b7e066cf854aa50f350096ce55e3bd691 /dhall/src/api
parente73f822b6972e8fa2e72b56ff5378b91bea1a5e6 (diff)
parent737abd9be6d35bbce784d9cf249edf7ad14677d6 (diff)
Merge remote-tracking branch 'origin/master' into fintan/canonicalize
Diffstat (limited to '')
-rw-r--r--dhall/src/api/mod.rs159
-rw-r--r--serde_dhall/src/serde.rs (renamed from dhall/src/api/serde.rs)52
-rw-r--r--serde_dhall/src/static_type.rs (renamed from dhall/src/api/static_type.rs)26
3 files changed, 38 insertions, 199 deletions
diff --git a/dhall/src/api/mod.rs b/dhall/src/api/mod.rs
deleted file mode 100644
index 188b6c0..0000000
--- a/dhall/src/api/mod.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-mod serde;
-pub(crate) mod static_type;
-
-pub use value::Value;
-
-mod value {
- use super::Type;
- use crate::error::Result;
- use crate::phase::{NormalizedSubExpr, Parsed, Typed};
-
- // A Dhall value
- pub struct Value(Typed);
-
- impl Value {
- pub fn from_str(s: &str, ty: Option<&Type>) -> Result<Self> {
- let resolved = Parsed::parse_str(s)?.resolve()?;
- let typed = match ty {
- None => resolved.typecheck()?,
- Some(t) => resolved.typecheck_with(&t.to_type())?,
- };
- Ok(Value(typed))
- }
- pub(crate) fn to_expr(&self) -> NormalizedSubExpr {
- self.0.to_expr()
- }
- pub(crate) fn to_typed(&self) -> Typed {
- self.0.clone()
- }
- }
-}
-
-pub use typ::Type;
-
-mod typ {
- use dhall_syntax::Builtin;
-
- use crate::core::thunk::{Thunk, TypeThunk};
- use crate::core::value::Value;
- use crate::error::Result;
- use crate::phase::{NormalizedSubExpr, Typed};
-
- /// 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 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()
- }
- pub(crate) fn to_type(&self) -> crate::phase::Type {
- self.0.to_type()
- }
- }
-
- impl crate::de::Deserialize for Type {
- fn from_dhall(v: &crate::api::Value) -> Result<Self> {
- Ok(Type(v.to_typed()))
- }
- }
-}
-
-/// Deserialization of Dhall expressions into Rust
-pub mod de {
- pub use super::static_type::StaticType;
- pub use super::{Type, Value};
- use crate::error::Result;
- #[doc(hidden)]
- pub use dhall_proc_macros::StaticType;
-
- /// 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.
- // TODO: seal trait
- pub trait Deserialize: Sized {
- /// See [dhall::de::from_str][crate::de::from_str]
- fn from_dhall(v: &Value) -> Result<Self>;
- }
-
- /// 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<T>(s: &str, ty: Option<&Type>) -> Result<T>
- where
- T: Deserialize,
- {
- T::from_dhall(&Value::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<T>(s: &str) -> Result<T>
- where
- T: Deserialize + StaticType,
- {
- from_str(s, Some(&<T as StaticType>::static_type()))
- }
-}
diff --git a/dhall/src/api/serde.rs b/serde_dhall/src/serde.rs
index e1c8eef..26708c1 100644
--- a/dhall/src/api/serde.rs
+++ b/serde_dhall/src/serde.rs
@@ -1,8 +1,11 @@
-use crate::api::de::{Deserialize, Value};
-use crate::error::{Error, Result};
-use dhall_syntax::{ExprF, SubExpr, X};
use std::borrow::Cow;
+use dhall::phase::NormalizedExpr;
+use dhall_syntax::ExprF;
+
+use crate::de::{Deserialize, Error, Result};
+use crate::Value;
+
impl<'a, T> Deserialize for T
where
T: serde::Deserialize<'a>,
@@ -12,16 +15,7 @@ where
}
}
-struct Deserializer<'a>(Cow<'a, SubExpr<X, X>>);
-
-impl serde::de::Error for Error {
- fn custom<T>(msg: T) -> Self
- where
- T: std::fmt::Display,
- {
- Error::Deserialize(msg.to_string())
- }
-}
+struct Deserializer<'a>(Cow<'a, NormalizedExpr>);
impl<'de: 'a, 'a> serde::de::IntoDeserializer<'de, Error> for Deserializer<'a> {
type Deserializer = Deserializer<'a>;
@@ -39,20 +33,24 @@ impl<'de: 'a, 'a> serde::Deserializer<'de> for Deserializer<'a> {
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!(),
- },
- },
+ NaturalLit(n) => {
+ if let Ok(n64) = (*n).try_into() {
+ visitor.visit_u64(n64)
+ } else if let Ok(n32) = (*n).try_into() {
+ visitor.visit_u32(n32)
+ } else {
+ unimplemented!()
+ }
+ }
+ IntegerLit(n) => {
+ if let Ok(n64) = (*n).try_into() {
+ visitor.visit_i64(n64)
+ } else if let Ok(n32) = (*n).try_into() {
+ visitor.visit_i32(n32)
+ } else {
+ unimplemented!()
+ }
+ }
RecordLit(m) => visitor.visit_map(
serde::de::value::MapDeserializer::new(m.iter().map(
|(k, v)| (k.as_ref(), Deserializer(Cow::Borrowed(v))),
diff --git a/dhall/src/api/static_type.rs b/serde_dhall/src/static_type.rs
index 906bcef..67a7bc4 100644
--- a/dhall/src/api/static_type.rs
+++ b/serde_dhall/src/static_type.rs
@@ -1,6 +1,6 @@
use dhall_syntax::{Builtin, Integer, Natural};
-use crate::api::Type;
+use crate::Value;
/// A Rust type that can be represented as a Dhall type.
///
@@ -14,14 +14,14 @@ use crate::api::Type;
/// [StaticType] because each different value would
/// have a different Dhall record type.
pub trait StaticType {
- fn static_type() -> Type;
+ fn static_type() -> Value;
}
macro_rules! derive_builtin {
($ty:ty, $builtin:ident) => {
impl StaticType for $ty {
- fn static_type() -> Type {
- Type::make_builtin_type(Builtin::$builtin)
+ fn static_type() -> Value {
+ Value::make_builtin_type(Builtin::$builtin)
}
}
};
@@ -38,8 +38,8 @@ where
A: StaticType,
B: StaticType,
{
- fn static_type() -> Type {
- Type::make_record_type(
+ fn static_type() -> Value {
+ Value::make_record_type(
vec![
("_1".to_owned(), A::static_type()),
("_2".to_owned(), B::static_type()),
@@ -54,8 +54,8 @@ where
T: StaticType,
E: StaticType,
{
- fn static_type() -> Type {
- Type::make_union_type(
+ fn static_type() -> Value {
+ Value::make_union_type(
vec![
("Ok".to_owned(), Some(T::static_type())),
("Err".to_owned(), Some(E::static_type())),
@@ -69,8 +69,8 @@ impl<T> StaticType for Option<T>
where
T: StaticType,
{
- fn static_type() -> Type {
- Type::make_optional_type(T::static_type())
+ fn static_type() -> Value {
+ Value::make_optional_type(T::static_type())
}
}
@@ -78,8 +78,8 @@ impl<T> StaticType for Vec<T>
where
T: StaticType,
{
- fn static_type() -> Type {
- Type::make_list_type(T::static_type())
+ fn static_type() -> Value {
+ Value::make_list_type(T::static_type())
}
}
@@ -87,7 +87,7 @@ impl<'a, T> StaticType for &'a T
where
T: StaticType,
{
- fn static_type() -> Type {
+ fn static_type() -> Value {
T::static_type()
}
}