diff options
author | Nadrieril | 2019-08-13 23:44:52 +0200 |
---|---|---|
committer | Nadrieril | 2019-08-13 23:45:27 +0200 |
commit | 66260f8e386f7a447352bd8ccbda064b00b698bc (patch) | |
tree | b3094a3d4e6b463724302b9be7e803a80ce4eed3 /dhall_syntax/src/core | |
parent | c600bae72198350b78fe19cf993b7f4c6f35225a (diff) |
Implement inline headers parsing
Diffstat (limited to '')
-rw-r--r-- | dhall_syntax/src/core/expr.rs | 17 | ||||
-rw-r--r-- | dhall_syntax/src/core/import.rs | 62 | ||||
-rw-r--r-- | dhall_syntax/src/core/visitor.rs | 4 |
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; |