summaryrefslogtreecommitdiff
path: root/dhall_syntax/src/core
diff options
context:
space:
mode:
authorNadrieril2019-08-13 23:44:52 +0200
committerNadrieril2019-08-13 23:45:27 +0200
commit66260f8e386f7a447352bd8ccbda064b00b698bc (patch)
treeb3094a3d4e6b463724302b9be7e803a80ce4eed3 /dhall_syntax/src/core
parentc600bae72198350b78fe19cf993b7f4c6f35225a (diff)
Implement inline headers parsing
Diffstat (limited to '')
-rw-r--r--dhall_syntax/src/core/expr.rs17
-rw-r--r--dhall_syntax/src/core/import.rs62
-rw-r--r--dhall_syntax/src/core/visitor.rs4
3 files changed, 63 insertions, 20 deletions
diff --git a/dhall_syntax/src/core/expr.rs b/dhall_syntax/src/core/expr.rs
index 9729efb..30ac4eb 100644
--- a/dhall_syntax/src/core/expr.rs
+++ b/dhall_syntax/src/core/expr.rs
@@ -258,7 +258,7 @@ pub enum ExprF<SubExpr, Embed> {
/// `e.{ x, y, z }`
Projection(SubExpr, DupTreeSet<Label>),
/// `./some/path`
- Import(Import),
+ Import(Import<SubExpr>),
/// Embeds the result of resolving an import
Embed(Embed),
}
@@ -323,7 +323,7 @@ impl<SE, E> ExprF<SE, E> {
impl<E> Expr<E> {
pub fn traverse_resolve<E2, Err>(
&self,
- visit_import: impl FnMut(&Import) -> Result<E2, Err>,
+ visit_import: impl FnMut(&Import<SubExpr<E2>>) -> Result<E2, Err>,
) -> Result<Expr<E2>, Err> {
self.traverse_resolve_with_visitor(&mut visitor::ResolveVisitor(
visit_import,
@@ -335,15 +335,20 @@ impl<E> Expr<E> {
visitor: &mut visitor::ResolveVisitor<F1>,
) -> Result<Expr<E2>, Err>
where
- F1: FnMut(&Import) -> Result<E2, Err>,
+ F1: FnMut(&Import<SubExpr<E2>>) -> Result<E2, Err>,
{
match self {
ExprF::BinOp(BinOp::ImportAlt, l, r) => l
.as_ref()
.traverse_resolve_with_visitor(visitor)
.or(r.as_ref().traverse_resolve_with_visitor(visitor)),
- ExprF::Import(import) => Ok(ExprF::Embed((visitor.0)(import)?)),
- _ => self.visit(visitor),
+ _ => {
+ let e = self.visit(&mut *visitor)?;
+ Ok(match &e {
+ ExprF::Import(import) => ExprF::Embed((visitor.0)(import)?),
+ _ => e,
+ })
+ }
}
}
}
@@ -373,7 +378,7 @@ impl<E> SubExpr<E> {
impl<E> SubExpr<E> {
pub fn traverse_resolve<E2, Err>(
&self,
- visit_import: impl FnMut(&Import) -> Result<E2, Err>,
+ visit_import: impl FnMut(&Import<SubExpr<E2>>) -> Result<E2, Err>,
) -> Result<SubExpr<E2>, Err> {
Ok(self.rewrap(self.as_ref().traverse_resolve(visit_import)?))
}
diff --git a/dhall_syntax/src/core/import.rs b/dhall_syntax/src/core/import.rs
index d41eae2..9329d48 100644
--- a/dhall_syntax/src/core/import.rs
+++ b/dhall_syntax/src/core/import.rs
@@ -13,21 +13,20 @@ pub enum FilePrefix {
/// The location of import (i.e. local vs. remote vs. environment)
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum ImportLocation {
+pub enum ImportLocation<SubExpr> {
Local(FilePrefix, Vec<String>),
- Remote(URL),
+ Remote(URL<SubExpr>),
Env(String),
Missing,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct URL {
+pub struct URL<SubExpr> {
pub scheme: Scheme,
pub authority: String,
pub path: Vec<String>,
pub query: Option<String>,
- // TODO: implement inline headers
- pub headers: Option<Box<ImportHashed>>,
+ pub headers: Option<SubExpr>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -49,15 +48,54 @@ pub enum Hash {
SHA256(Vec<u8>),
}
+/// Reference to an external resource
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ImportHashed {
- pub location: ImportLocation,
+pub struct Import<SubExpr> {
+ pub mode: ImportMode,
+ pub location: ImportLocation<SubExpr>,
pub hash: Option<Hash>,
}
-/// Reference to an external resource
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Import {
- pub mode: ImportMode,
- pub location_hashed: ImportHashed,
+impl<SE> URL<SE> {
+ pub fn visit_subexpr<'a, Err, SE2>(
+ &'a self,
+ f: impl FnOnce(&'a SE) -> Result<SE2, Err>,
+ ) -> Result<URL<SE2>, Err> {
+ let headers = self.headers.as_ref().map(f).transpose()?;
+ Ok(URL {
+ scheme: self.scheme,
+ authority: self.authority.clone(),
+ path: self.path.clone(),
+ query: self.query.clone(),
+ headers,
+ })
+ }
+}
+
+impl<SE> ImportLocation<SE> {
+ pub fn visit_subexpr<'a, Err, SE2>(
+ &'a self,
+ f: impl FnOnce(&'a SE) -> Result<SE2, Err>,
+ ) -> Result<ImportLocation<SE2>, Err> {
+ use ImportLocation::*;
+ Ok(match self {
+ Local(prefix, path) => Local(prefix.clone(), path.clone()),
+ Remote(url) => Remote(url.visit_subexpr(f)?),
+ Env(env) => Env(env.clone()),
+ Missing => Missing,
+ })
+ }
+}
+
+impl<SE> Import<SE> {
+ pub fn visit_subexpr<'a, Err, SE2>(
+ &'a self,
+ f: impl FnOnce(&'a SE) -> Result<SE2, Err>,
+ ) -> Result<Import<SE2>, Err> {
+ Ok(Import {
+ mode: self.mode,
+ location: self.location.visit_subexpr(f)?,
+ hash: self.hash.clone(),
+ })
+ }
}
diff --git a/dhall_syntax/src/core/visitor.rs b/dhall_syntax/src/core/visitor.rs
index f3d9194..7b4ed4b 100644
--- a/dhall_syntax/src/core/visitor.rs
+++ b/dhall_syntax/src/core/visitor.rs
@@ -153,7 +153,7 @@ where
Field(e, l) => Field(v.visit_subexpr(e)?, l.clone()),
Projection(e, ls) => Projection(v.visit_subexpr(e)?, ls.clone()),
Assert(e) => Assert(v.visit_subexpr(e)?),
- Import(a) => Import(a.clone()),
+ Import(i) => Import(i.visit_subexpr(|e| v.visit_subexpr(e))?),
Embed(a) => Embed(v.visit_embed(a)?),
})
}
@@ -251,7 +251,7 @@ impl<'a, 'b, E, E2, Err, F1>
ExprFFallibleVisitor<'a, SubExpr<E>, SubExpr<E2>, E, E2>
for &'b mut ResolveVisitor<F1>
where
- F1: FnMut(&Import) -> Result<E2, Err>,
+ F1: FnMut(&Import<SubExpr<E2>>) -> Result<E2, Err>,
{
type Error = Err;