summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2019-03-24 16:25:37 +0100
committerNadrieril2019-03-24 16:25:37 +0100
commit8bae9a8fab523668e9aea96e4f32cec21e22998a (patch)
tree09763096bd270981978152226f9b780dbd22153b
parent6c1a739687f706cf6630c55f8d53c92aacaf6e3d (diff)
Parser import hash and headers
-rw-r--r--dhall/src/binary.rs35
-rw-r--r--dhall/src/imports.rs2
-rw-r--r--dhall/tests/parser.rs2
-rw-r--r--dhall_core/src/import.rs18
-rw-r--r--dhall_core/src/parser.rs31
-rw-r--r--dhall_core/src/printer.rs23
6 files changed, 86 insertions, 25 deletions
diff --git a/dhall/src/binary.rs b/dhall/src/binary.rs
index a028e82..eb96da2 100644
--- a/dhall/src/binary.rs
+++ b/dhall/src/binary.rs
@@ -179,11 +179,26 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> {
.collect::<Result<_, _>>()?,
)))
}
- [U64(24), _hash, U64(mode), U64(scheme), rest..] => {
+ [U64(24), hash, U64(mode), U64(scheme), rest..] => {
let mode = match mode {
1 => ImportMode::RawText,
_ => ImportMode::Code,
};
+ let hash = match hash {
+ Null => None,
+ Array(vec) => match vec.as_slice() {
+ [String(protocol), String(hash)] => Some(Hash {
+ protocol: protocol.clone(),
+ hash: hash.clone(),
+ }),
+ _ => Err(DecodeError::WrongFormatError(
+ "import/hash".to_owned(),
+ ))?,
+ },
+ _ => Err(DecodeError::WrongFormatError(
+ "import/hash".to_owned(),
+ ))?,
+ };
let mut rest = rest.iter();
let location = match scheme {
0 | 1 => {
@@ -191,8 +206,18 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> {
0 => Scheme::HTTP,
_ => Scheme::HTTPS,
};
- let _headers = match rest.next() {
- Some(Null) => (),
+ let headers = match rest.next() {
+ Some(Null) => None,
+ Some(x) => {
+ match cbor_value_to_dhall(&x)?.as_ref() {
+ Embed(import) => Some(Box::new(
+ import.location_hashed.clone(),
+ )),
+ _ => Err(DecodeError::WrongFormatError(
+ "import/remote/headers".to_owned(),
+ ))?,
+ }
+ }
_ => Err(DecodeError::WrongFormatError(
"import/remote/headers".to_owned(),
))?,
@@ -224,6 +249,7 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> {
authority,
path,
query,
+ headers,
})
}
2 | 3 | 4 | 5 => {
@@ -263,8 +289,7 @@ fn cbor_value_to_dhall(data: &cbor::Value) -> Result<ParsedExpr, DecodeError> {
};
Embed(Import {
mode,
- hash: None,
- location,
+ location_hashed: ImportHashed { hash, location },
})
}
[U64(25), bindings..] => {
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index 8a2edce..8df4e97 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -29,7 +29,7 @@ fn resolve_import(
let cwd = match root {
LocalDir(cwd) => cwd,
};
- match &import.location {
+ match &import.location_hashed.location {
Local(prefix, path) => {
let path = match prefix {
Parent => cwd.parent().unwrap().join(path),
diff --git a/dhall/tests/parser.rs b/dhall/tests/parser.rs
index 5f57068..1db8d33 100644
--- a/dhall/tests/parser.rs
+++ b/dhall/tests/parser.rs
@@ -42,7 +42,7 @@ parser_success!(spec_parser_success_multilet, "multilet");
parser_success!(spec_parser_success_natural, "natural");
parser_success!(spec_parser_success_nestedBlockComment, "nestedBlockComment");
parser_success!(spec_parser_success_operators, "operators");
-// parser_success!(spec_parser_success_parenthesizeUsing, "parenthesizeUsing");
+parser_success!(spec_parser_success_parenthesizeUsing, "parenthesizeUsing");
parser_success!(spec_parser_success_pathTermination, "pathTermination");
parser_success!(spec_parser_success_paths, "paths");
parser_success!(spec_parser_success_quotedLabel, "quotedLabel");
diff --git a/dhall_core/src/import.rs b/dhall_core/src/import.rs
index 21bd370..f039953 100644
--- a/dhall_core/src/import.rs
+++ b/dhall_core/src/import.rs
@@ -28,7 +28,7 @@ pub struct URL {
pub authority: String,
pub path: PathBuf,
pub query: Option<String>,
- // pub headers: Option<ImportHashed>,
+ pub headers: Option<Box<ImportHashed>>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -44,11 +44,21 @@ pub enum ImportMode {
RawText,
}
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Hash {
+ pub protocol: String,
+ pub hash: String,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ImportHashed {
+ pub location: ImportLocation,
+ pub hash: Option<Hash>,
+}
+
/// Reference to an external resource
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Import {
pub mode: ImportMode,
- pub location: ImportLocation,
- // TODO
- pub hash: Option<()>,
+ pub location_hashed: ImportHashed,
}
diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs
index 4f26b0f..3d5a761 100644
--- a/dhall_core/src/parser.rs
+++ b/dhall_core/src/parser.rs
@@ -431,12 +431,14 @@ make_parser! {
authority: auth,
path: p,
query: None,
+ headers: None,
},
[scheme(sch), authority(auth), path(p), query(q)] => URL {
scheme: sch,
authority: auth,
path: p,
query: Some(q),
+ headers: None,
},
));
@@ -444,9 +446,10 @@ make_parser! {
rule!(query<String>; captured_str!(s) => s.to_owned());
- // TODO: headers
rule!(http<URL>; children!(
- [http_raw(url)] => url
+ [http_raw(url)] => url,
+ [http_raw(url), import_hashed(import_hashed)] =>
+ URL { headers: Some(Box::new(import_hashed)), ..url },
));
rule!(env<String>; children!(
@@ -458,7 +461,6 @@ make_parser! {
rule!(missing<()>; captured_str!(_) => ());
- // TODO: other import types
rule!(import_type<ImportLocation>; children!(
[missing(_)] => {
ImportLocation::Missing
@@ -474,9 +476,16 @@ make_parser! {
},
));
- rule!(import_hashed<(ImportLocation, Option<()>)>; children!(
- // TODO: handle hash
- [import_type(import)] => (import, None)
+ rule!(hash<Hash>; captured_str!(s) =>
+ Hash {
+ protocol: s.trim()[..6].to_owned(),
+ hash: s.trim()[7..].to_owned(),
+ }
+ );
+
+ rule!(import_hashed<ImportHashed>; children!(
+ [import_type(location)] => ImportHashed { location, hash: None },
+ [import_type(location), hash(hash)] => ImportHashed { location, hash: Some(hash) },
));
rule_group!(expression<ParsedExpr>);
@@ -484,18 +493,16 @@ make_parser! {
rule!(Text<()>; captured_str!(_) => ());
rule!(import<ParsedExpr> as expression; children!(
- [import_hashed((location, hash))] => {
+ [import_hashed(location_hashed)] => {
bx(Expr::Embed(Import {
mode: ImportMode::Code,
- hash,
- location,
+ location_hashed
}))
},
- [import_hashed((location, hash)), Text(_)] => {
+ [import_hashed(location_hashed), Text(_)] => {
bx(Expr::Embed(Import {
mode: ImportMode::RawText,
- hash,
- location,
+ location_hashed
}))
},
));
diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs
index 9525904..1d1b063 100644
--- a/dhall_core/src/printer.rs
+++ b/dhall_core/src/printer.rs
@@ -326,12 +326,16 @@ impl Display for Label {
}
}
-impl Display for Import {
+impl Display for Hash {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(f, "{}:{}", self.protocol, self.hash)
+ }
+}
+impl Display for ImportHashed {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use std::path::PathBuf;
use FilePrefix::*;
use ImportLocation::*;
- use ImportMode::*;
let quoted = |s: &str| -> String {
if s.chars().all(|c| c.is_ascii_alphanumeric()) {
s.to_owned()
@@ -364,6 +368,9 @@ impl Display for Import {
if let Some(q) = &url.query {
write!(f, "?{}", q)?
}
+ if let Some(h) = &url.headers {
+ write!(f, " using ({})", h)?
+ }
}
Env(e) => {
write!(f, "env:{}", quoted(e))?;
@@ -372,6 +379,18 @@ impl Display for Import {
write!(f, "missing")?;
}
}
+ if let Some(hash) = &self.hash {
+ write!(f, " ")?;
+ hash.fmt(f)?;
+ }
+ Ok(())
+ }
+}
+
+impl Display for Import {
+ fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ self.location_hashed.fmt(f)?;
+ use ImportMode::*;
match self.mode {
Code => {}
RawText => write!(f, " as Text")?,