From 8d45d633dfa60e8d64c9e6e742de4e33496bf0fa Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 13 Aug 2019 22:11:45 +0200 Subject: Store Imports in their own node instead of in Embed --- dhall/src/phase/binary.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'dhall/src/phase/binary.rs') diff --git a/dhall/src/phase/binary.rs b/dhall/src/phase/binary.rs index 3292617..b3a80aa 100644 --- a/dhall/src/phase/binary.rs +++ b/dhall/src/phase/binary.rs @@ -19,7 +19,6 @@ pub fn decode(data: &[u8]) -> Result { } } -//TODO: encode normalized expression too pub fn encode(expr: &ParsedSubExpr) -> Result, EncodeError> { serde_cbor::ser::to_vec(&Serialize::Expr(expr)) .map_err(|e| EncodeError::CBORError(e)) @@ -264,7 +263,7 @@ fn cbor_value_to_dhall( // TODO // Some(x) => { // match cbor_value_to_dhall(&x)?.as_ref() { - // Embed(import) => Some(Box::new( + // Import(import) => Some(Box::new( // import.location_hashed.clone(), // )), // _ => Err(DecodeError::WrongFormatError( @@ -340,7 +339,7 @@ fn cbor_value_to_dhall( "import/type".to_owned(), ))?, }; - Embed(Import { + Import(dhall_syntax::Import { mode, location_hashed: ImportHashed { hash, location }, }) @@ -573,7 +572,10 @@ where .chain(once(expr(x))) .chain(ls.iter().map(label)), ), - Embed(import) => serialize_import(ser, import), + Import(import) => serialize_import(ser, import), + Embed(_) => unimplemented!( + "An expression with resolved imports cannot be binary-encoded" + ), } } @@ -631,12 +633,14 @@ where ImportLocation::Remote(url) => { match &url.headers { None => ser_seq.serialize_element(&Null)?, - Some(location_hashed) => ser_seq.serialize_element( - &self::Serialize::Expr(&rc(ExprF::Embed(Import { - mode: ImportMode::Code, - location_hashed: location_hashed.as_ref().clone(), - }))), - )?, + Some(location_hashed) => { + ser_seq.serialize_element(&self::Serialize::Expr(&rc( + ExprF::Import(dhall_syntax::Import { + mode: ImportMode::Code, + location_hashed: location_hashed.as_ref().clone(), + }), + )))? + } }; ser_seq.serialize_element(&url.authority)?; for p in &url.path { -- cgit v1.2.3 From c600bae72198350b78fe19cf993b7f4c6f35225a Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 13 Aug 2019 23:08:48 +0200 Subject: Implement Hash for ParsedSubExpr --- dhall/src/phase/binary.rs | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'dhall/src/phase/binary.rs') diff --git a/dhall/src/phase/binary.rs b/dhall/src/phase/binary.rs index b3a80aa..9ed823c 100644 --- a/dhall/src/phase/binary.rs +++ b/dhall/src/phase/binary.rs @@ -10,7 +10,7 @@ use dhall_syntax::{ }; use crate::error::{DecodeError, EncodeError}; -use crate::phase::{DecodedSubExpr, ParsedSubExpr}; +use crate::phase::DecodedSubExpr; pub fn decode(data: &[u8]) -> Result { match serde_cbor::de::from_slice(data) { @@ -19,7 +19,7 @@ pub fn decode(data: &[u8]) -> Result { } } -pub fn encode(expr: &ParsedSubExpr) -> Result, EncodeError> { +pub fn encode(expr: &SubExpr) -> Result, EncodeError> { serde_cbor::ser::to_vec(&Serialize::Expr(expr)) .map_err(|e| EncodeError::CBORError(e)) } @@ -423,11 +423,11 @@ where .collect::>() } -enum Serialize<'a> { - Expr(&'a ParsedSubExpr), +enum Serialize<'a, E> { + Expr(&'a SubExpr), CBOR(cbor::Value), - RecordMap(&'a DupTreeMap), - UnionMap(&'a DupTreeMap>), + RecordMap(&'a DupTreeMap>), + UnionMap(&'a DupTreeMap>>), } macro_rules! count { @@ -447,7 +447,7 @@ macro_rules! ser_seq { }}; } -fn serialize_subexpr(ser: S, e: &ParsedSubExpr) -> Result +fn serialize_subexpr(ser: S, e: &SubExpr) -> Result where S: serde::ser::Serializer, { @@ -457,21 +457,14 @@ where use std::iter::once; use self::Serialize::{RecordMap, UnionMap}; - fn expr(x: &ParsedSubExpr) -> self::Serialize<'_> { + fn expr(x: &SubExpr) -> self::Serialize<'_, E> { self::Serialize::Expr(x) } - fn cbor<'a>(v: cbor::Value) -> self::Serialize<'a> { - self::Serialize::CBOR(v) - } - fn tag<'a>(x: u64) -> self::Serialize<'a> { - cbor(U64(x)) - } - fn null<'a>() -> self::Serialize<'a> { - cbor(cbor::Value::Null) - } - fn label<'a>(l: &Label) -> self::Serialize<'a> { - cbor(cbor::Value::String(l.into())) - } + let cbor = + |v: cbor::Value| -> self::Serialize<'_, E> { self::Serialize::CBOR(v) }; + let tag = |x: u64| cbor(U64(x)); + let null = || cbor(cbor::Value::Null); + let label = |l: &Label| cbor(cbor::Value::String(l.into())); match e.as_ref() { Const(c) => ser.serialize_str(&c.to_string()), @@ -634,12 +627,14 @@ where match &url.headers { None => ser_seq.serialize_element(&Null)?, Some(location_hashed) => { - ser_seq.serialize_element(&self::Serialize::Expr(&rc( + let e = rc( ExprF::Import(dhall_syntax::Import { mode: ImportMode::Code, location_hashed: location_hashed.as_ref().clone(), }), - )))? + ); + let s: Serialize<'_, ()> = self::Serialize::Expr(&e); + ser_seq.serialize_element(&s)? } }; ser_seq.serialize_element(&url.authority)?; @@ -665,7 +660,7 @@ where ser_seq.end() } -impl<'a> serde::ser::Serialize for Serialize<'a> { +impl<'a, E> serde::ser::Serialize for Serialize<'a, E> { fn serialize(&self, ser: S) -> Result where S: serde::ser::Serializer, -- cgit v1.2.3 From 66260f8e386f7a447352bd8ccbda064b00b698bc Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Tue, 13 Aug 2019 23:44:52 +0200 Subject: Implement inline headers parsing --- dhall/src/phase/binary.rs | 50 ++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) (limited to 'dhall/src/phase/binary.rs') diff --git a/dhall/src/phase/binary.rs b/dhall/src/phase/binary.rs index 9ed823c..36dd471 100644 --- a/dhall/src/phase/binary.rs +++ b/dhall/src/phase/binary.rs @@ -4,9 +4,8 @@ use std::iter::FromIterator; use dhall_syntax::map::DupTreeMap; use dhall_syntax::{ - rc, ExprF, FilePrefix, Hash, Import, ImportHashed, ImportLocation, - ImportMode, Integer, InterpolatedText, Label, Natural, Scheme, SubExpr, - URL, V, + rc, ExprF, FilePrefix, Hash, Import, ImportLocation, ImportMode, Integer, + InterpolatedText, Label, Natural, Scheme, SubExpr, URL, V, }; use crate::error::{DecodeError, EncodeError}; @@ -260,20 +259,12 @@ fn cbor_value_to_dhall( }; let headers = match rest.next() { Some(Null) => None, - // TODO - // Some(x) => { - // match cbor_value_to_dhall(&x)?.as_ref() { - // Import(import) => Some(Box::new( - // import.location_hashed.clone(), - // )), - // _ => Err(DecodeError::WrongFormatError( - // "import/remote/headers".to_owned(), - // ))?, - // } - // } + Some(x) => { + let x = cbor_value_to_dhall(&x)?; + Some(x) + } _ => Err(DecodeError::WrongFormatError( - "import/remote/headers is unimplemented" - .to_owned(), + "import/remote/headers".to_owned(), ))?, }; let authority = match rest.next() { @@ -341,7 +332,8 @@ fn cbor_value_to_dhall( }; Import(dhall_syntax::Import { mode, - location_hashed: ImportHashed { hash, location }, + hash, + location, }) } [U64(25), bindings..] => { @@ -572,14 +564,17 @@ where } } -fn serialize_import(ser: S, import: &Import) -> Result +fn serialize_import( + ser: S, + import: &Import>, +) -> Result where S: serde::ser::Serializer, { use cbor::Value::{Bytes, Null, U64}; use serde::ser::SerializeSeq; - let count = 4 + match &import.location_hashed.location { + let count = 4 + match &import.location { ImportLocation::Remote(url) => 3 + url.path.len(), ImportLocation::Local(_, path) => path.len(), ImportLocation::Env(_) => 1, @@ -589,7 +584,7 @@ where ser_seq.serialize_element(&U64(24))?; - let hash = match &import.location_hashed.hash { + let hash = match &import.hash { None => Null, Some(Hash::SHA256(h)) => { let mut bytes = vec![18, 32]; @@ -606,7 +601,7 @@ where }; ser_seq.serialize_element(&U64(mode))?; - let scheme = match &import.location_hashed.location { + let scheme = match &import.location { ImportLocation::Remote(url) => match url.scheme { Scheme::HTTP => 0, Scheme::HTTPS => 1, @@ -622,19 +617,12 @@ where }; ser_seq.serialize_element(&U64(scheme))?; - match &import.location_hashed.location { + match &import.location { ImportLocation::Remote(url) => { match &url.headers { None => ser_seq.serialize_element(&Null)?, - Some(location_hashed) => { - let e = rc( - ExprF::Import(dhall_syntax::Import { - mode: ImportMode::Code, - location_hashed: location_hashed.as_ref().clone(), - }), - ); - let s: Serialize<'_, ()> = self::Serialize::Expr(&e); - ser_seq.serialize_element(&s)? + Some(e) => { + ser_seq.serialize_element(&self::Serialize::Expr(e))? } }; ser_seq.serialize_element(&url.authority)?; -- cgit v1.2.3