summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dhall/src/expr.rs35
-rw-r--r--dhall/src/imports.rs27
-rw-r--r--dhall/src/tests.rs3
-rw-r--r--dhall/src/traits/deserialize.rs8
-rw-r--r--dhall/src/typecheck.rs2
5 files changed, 52 insertions, 23 deletions
diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs
index 1ce20e3..e3a2fe5 100644
--- a/dhall/src/expr.rs
+++ b/dhall/src/expr.rs
@@ -1,5 +1,6 @@
use crate::imports::ImportRoot;
use dhall_core::*;
+use std::marker::PhantomData;
macro_rules! derive_other_traits {
($ty:ident) => {
@@ -20,13 +21,39 @@ macro_rules! derive_other_traits {
};
}
+macro_rules! derive_other_traits_ {
+ ($ty:ident) => {
+ impl<'a> std::cmp::PartialEq for $ty<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+
+ impl<'a> std::fmt::Display for $ty<'a> {
+ fn fmt(
+ &self,
+ f: &mut std::fmt::Formatter,
+ ) -> Result<(), std::fmt::Error> {
+ self.0.fmt(f)
+ }
+ }
+ };
+}
+
#[derive(Debug, Clone, Eq)]
-pub struct Parsed(pub(crate) SubExpr<X, Import>, pub(crate) ImportRoot);
-derive_other_traits!(Parsed);
+pub struct Parsed<'a>(
+ pub(crate) SubExpr<X, Import>,
+ pub(crate) ImportRoot,
+ pub(crate) PhantomData<&'a ()>,
+);
+derive_other_traits_!(Parsed);
#[derive(Debug, Clone, Eq)]
-pub struct Resolved(pub(crate) SubExpr<X, Normalized>);
-derive_other_traits!(Resolved);
+pub struct Resolved<'a>(
+ pub(crate) SubExpr<X, Normalized>,
+ pub(crate) PhantomData<&'a ()>,
+);
+derive_other_traits_!(Resolved);
#[derive(Debug, Clone, Eq)]
pub struct Typed(pub(crate) SubExpr<X, Normalized>, pub(crate) Option<Type>);
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index b5546b2..6b6e2e7 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -3,6 +3,7 @@ use crate::expr::*;
use dhall_core::*;
use std::fs::File;
use std::io::Read;
+use std::marker::PhantomData;
use std::path::Path;
use std::path::PathBuf;
@@ -48,10 +49,10 @@ fn load_import(f: &Path) -> Result<Normalized, Error> {
Ok(Parsed::parse_file(f)?.resolve()?.typecheck()?.normalize())
}
-fn resolve_expr(
- Parsed(expr, root): Parsed,
+fn resolve_expr<'a>(
+ Parsed(expr, root, marker): Parsed<'a>,
allow_imports: bool,
-) -> Result<Resolved, ImportError> {
+) -> Result<Resolved<'a>, ImportError> {
let resolve = |import: &Import| -> Result<Normalized, ImportError> {
if allow_imports {
let expr = resolve_import(import, &root)?;
@@ -61,36 +62,36 @@ fn resolve_expr(
}
};
let expr = expr.as_ref().traverse_embed(&resolve)?;
- Ok(Resolved(rc(expr)))
+ Ok(Resolved(rc(expr), marker))
}
-impl Parsed {
- pub fn parse_file(f: &Path) -> Result<Parsed, Error> {
+impl<'a> Parsed<'a> {
+ pub fn parse_file(f: &Path) -> Result<Parsed<'a>, Error> {
let mut buffer = String::new();
File::open(f)?.read_to_string(&mut buffer)?;
let expr = parse_expr(&*buffer)?;
let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned());
- Ok(Parsed(expr, root))
+ Ok(Parsed(expr, root, PhantomData))
}
- pub fn parse_str(s: &str) -> Result<Parsed, Error> {
+ pub fn parse_str(s: &'a str) -> Result<Parsed<'a>, Error> {
let expr = parse_expr(s)?;
let root = ImportRoot::LocalDir(std::env::current_dir()?);
- Ok(Parsed(expr, root))
+ Ok(Parsed(expr, root, PhantomData))
}
- pub fn parse_binary_file(f: &Path) -> Result<Parsed, Error> {
+ pub fn parse_binary_file(f: &Path) -> Result<Parsed<'a>, Error> {
let mut buffer = Vec::new();
File::open(f)?.read_to_end(&mut buffer)?;
let expr = crate::binary::decode(&buffer)?;
let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned());
- Ok(Parsed(expr, root))
+ Ok(Parsed(expr, root, PhantomData))
}
- pub fn resolve(self) -> Result<Resolved, ImportError> {
+ pub fn resolve(self) -> Result<Resolved<'a>, ImportError> {
crate::imports::resolve_expr(self, true)
}
- pub fn skip_resolve(self) -> Result<Resolved, ImportError> {
+ pub fn skip_resolve(self) -> Result<Resolved<'a>, ImportError> {
crate::imports::resolve_expr(self, false)
}
}
diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs
index 798f3e9..14c2a5f 100644
--- a/dhall/src/tests.rs
+++ b/dhall/src/tests.rs
@@ -99,7 +99,8 @@ pub fn run_test(
assert_eq_pretty!(expr, expected);
// Round-trip pretty-printer
- let expr: Parsed = crate::from_str(&expr.to_string(), None)?;
+ let expr_string = expr.to_string();
+ let expr: Parsed = crate::from_str(&expr_string, None)?;
assert_eq!(expr, expected);
return Ok(());
diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs
index 1fbdfe1..3e8cc5e 100644
--- a/dhall/src/traits/deserialize.rs
+++ b/dhall/src/traits/deserialize.rs
@@ -5,18 +5,18 @@ pub trait Deserialize<'a>: Sized {
fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self>;
}
-impl<'a> Deserialize<'a> for Parsed {
+impl<'de: 'a, 'a> Deserialize<'de> for Parsed<'a> {
/// Simply parses the provided string. Ignores the
/// provided type.
- fn from_str(s: &'a str, _: Option<&Type>) -> Result<Self> {
+ fn from_str(s: &'de str, _: Option<&Type>) -> Result<Self> {
Ok(Parsed::parse_str(s)?)
}
}
-impl<'a> Deserialize<'a> for Resolved {
+impl<'de: 'a, 'a> Deserialize<'de> for Resolved<'a> {
/// Parses and resolves the provided string. Ignores the
/// provided type.
- fn from_str(s: &'a str, ty: Option<&Type>) -> Result<Self> {
+ fn from_str(s: &'de str, ty: Option<&Type>) -> Result<Self> {
Ok(Parsed::from_str(s, ty)?.resolve()?)
}
}
diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs
index 4881972..41c1b69 100644
--- a/dhall/src/typecheck.rs
+++ b/dhall/src/typecheck.rs
@@ -11,7 +11,7 @@ use dhall_generator as dhall;
use self::TypeMessage::*;
-impl Resolved {
+impl<'a> Resolved<'a> {
pub fn typecheck(self) -> Result<Typed, TypeError> {
type_of(self.0.clone())
}