From 58f10a2a274fe858da6cc73d4a33718bfc46d52b Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 19:17:34 +0200 Subject: s/load_from/parse/ --- dhall/src/imports.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'dhall/src/imports.rs') diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index fdde8c3..a65be4f 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -90,7 +90,7 @@ fn resolve_expr( } impl Parsed { - pub fn load_from_file(f: &Path) -> Result { + pub fn parse_file(f: &Path) -> Result { let mut buffer = String::new(); File::open(f)?.read_to_string(&mut buffer)?; let expr = parse_expr(&*buffer)?; @@ -98,13 +98,13 @@ impl Parsed { Ok(Parsed(expr, root)) } - pub fn load_from_str(s: &str) -> Result { + pub fn parse_str(s: &str) -> Result { let expr = parse_expr(s)?; let root = ImportRoot::LocalDir(std::env::current_dir()?); Ok(Parsed(expr, root)) } - pub fn load_from_binary_file(f: &Path) -> Result { + pub fn parse_binary_file(f: &Path) -> Result { let mut buffer = Vec::new(); File::open(f)?.read_to_end(&mut buffer)?; let expr = crate::binary::decode(&buffer)?; @@ -125,7 +125,7 @@ pub fn load_dhall_file( f: &Path, resolve_imports: bool, ) -> Result, ImportError> { - let expr = Parsed::load_from_file(f)?; + let expr = Parsed::parse_file(f)?; let expr = resolve_expr(expr, resolve_imports)?; Ok(expr.0.unroll()) } -- cgit v1.3.1 From c7184b841279a55bdfb39bde429896d221aa666c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 21:46:25 +0200 Subject: Cleanup error handling Closes #41 --- Cargo.lock | 7 ++++++ dhall/Cargo.toml | 1 + dhall/src/error.rs | 25 +++++++++++++++++-- dhall/src/imports.rs | 54 ++++++++++++----------------------------- dhall/src/tests.rs | 21 +++++++--------- dhall/src/traits/deserialize.rs | 6 ++--- 6 files changed, 58 insertions(+), 56 deletions(-) (limited to 'dhall/src/imports.rs') diff --git a/Cargo.lock b/Cargo.lock index 781c593..e0a55ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,6 +73,7 @@ dependencies = [ "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lalrpop-util 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)", "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_cbor 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "term-painter 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -265,6 +266,11 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "quick-error" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.6.11" @@ -448,6 +454,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pretty 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f60c0d9f6fc88ecdd245d90c1920ff76a430ab34303fc778d33b1d0a4c3bf6d3" "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)" = "aa5f7c20820475babd2c077c3ab5f8c77a31c15e16ea38687b4c02d3e48680f4" diff --git a/dhall/Cargo.toml b/dhall/Cargo.toml index 7aa8b4f..a7c21dd 100644 --- a/dhall/Cargo.toml +++ b/dhall/Cargo.toml @@ -16,6 +16,7 @@ bytecount = "0.5.1" itertools = "0.8.0" lalrpop-util = "0.16.3" term-painter = "0.2.3" +quick-error = "1.2.2" serde = { version = "1.0", features = ["derive"] } serde_cbor = "0.9.0" dhall_core = { path = "../dhall_core" } diff --git a/dhall/src/error.rs b/dhall/src/error.rs index ef8dd34..eba7ff5 100644 --- a/dhall/src/error.rs +++ b/dhall/src/error.rs @@ -1,3 +1,24 @@ -// TODO -pub type Error = (); +use quick_error::quick_error; + pub type Result = std::result::Result; + +quick_error! { + #[derive(Debug)] + pub enum Error { + IO(err: std::io::Error) { + from() + } + Parse(err: dhall_core::ParseError) { + from() + } + Decode(err: crate::binary::DecodeError) { + from() + } + Resolve(err: crate::imports::ImportError) { + from() + } + Typecheck(err: crate::typecheck::TypeError) { + from() + } + } +} diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index a65be4f..3c33b4e 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -1,46 +1,20 @@ // use dhall_core::{Expr, FilePrefix, Import, ImportLocation, ImportMode, X}; use dhall_core::{Expr, Import, X}; // use std::path::Path; -use crate::binary::DecodeError; +use crate::error::Error; use crate::expr::*; use dhall_core::*; -use std::fmt; +use quick_error::quick_error; use std::fs::File; use std::io::Read; use std::path::Path; use std::path::PathBuf; -#[derive(Debug)] -pub enum ImportError { - ParseError(ParseError), - BinaryDecodeError(DecodeError), - IOError(std::io::Error), - UnexpectedImportError(Import), -} -impl From for ImportError { - fn from(e: ParseError) -> Self { - ImportError::ParseError(e) - } -} -impl From for ImportError { - fn from(e: DecodeError) -> Self { - ImportError::BinaryDecodeError(e) - } -} -impl From for ImportError { - fn from(e: std::io::Error) -> Self { - ImportError::IOError(e) - } -} -impl fmt::Display for ImportError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - use self::ImportError::*; - match self { - ParseError(e) => e.fmt(f), - BinaryDecodeError(_) => unimplemented!(), - IOError(e) => e.fmt(f), - UnexpectedImportError(e) => e.fmt(f), - } +quick_error! { + #[derive(Debug)] + pub enum ImportError { + Recursive(import: Import, err: Box) {} + UnexpectedImport(import: Import) {} } } @@ -67,7 +41,9 @@ fn resolve_import( Here => cwd.join(path), _ => unimplemented!("{:?}", import), }; - load_dhall_file(&path, true) + Ok(load_dhall_file(&path, true).map_err(|e| { + ImportError::Recursive(import.clone(), Box::new(e)) + })?) } _ => unimplemented!("{:?}", import), } @@ -82,7 +58,7 @@ fn resolve_expr( let expr = resolve_import(import, &root)?; Ok(expr.roll()) } else { - Err(ImportError::UnexpectedImportError(import.clone())) + Err(ImportError::UnexpectedImport(import.clone())) } }; let expr = expr.as_ref().traverse_embed(&resolve)?; @@ -90,7 +66,7 @@ fn resolve_expr( } impl Parsed { - pub fn parse_file(f: &Path) -> Result { + pub fn parse_file(f: &Path) -> Result { let mut buffer = String::new(); File::open(f)?.read_to_string(&mut buffer)?; let expr = parse_expr(&*buffer)?; @@ -98,13 +74,13 @@ impl Parsed { Ok(Parsed(expr, root)) } - pub fn parse_str(s: &str) -> Result { + pub fn parse_str(s: &str) -> Result { let expr = parse_expr(s)?; let root = ImportRoot::LocalDir(std::env::current_dir()?); Ok(Parsed(expr, root)) } - pub fn parse_binary_file(f: &Path) -> Result { + pub fn parse_binary_file(f: &Path) -> Result { let mut buffer = Vec::new(); File::open(f)?.read_to_end(&mut buffer)?; let expr = crate::binary::decode(&buffer)?; @@ -124,7 +100,7 @@ impl Parsed { pub fn load_dhall_file( f: &Path, resolve_imports: bool, -) -> Result, ImportError> { +) -> Result, Error> { let expr = Parsed::parse_file(f)?; let expr = resolve_expr(expr, resolve_imports)?; Ok(expr.0.unroll()) diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 737a8a4..9e78c2f 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -29,7 +29,8 @@ macro_rules! make_spec_test { }; } -use crate::imports::ImportError; +use crate::error::{Error, Result}; +use crate::expr::Parsed; use crate::*; use dhall_core::*; use dhall_generator as dhall; @@ -47,20 +48,16 @@ pub enum Feature { } // Deprecated -fn read_dhall_file<'i>(file_path: &str) -> Result, ImportError> { +fn read_dhall_file<'i>(file_path: &str) -> Result> { crate::imports::load_dhall_file(&PathBuf::from(file_path), true) } -fn parse_file_str<'i>( - file_path: &str, -) -> Result { - crate::expr::Parsed::parse_file(&PathBuf::from(file_path)) +fn parse_file_str<'i>(file_path: &str) -> Result { + Parsed::parse_file(&PathBuf::from(file_path)) } -fn parse_binary_file_str<'i>( - file_path: &str, -) -> Result { - crate::expr::Parsed::parse_binary_file(&PathBuf::from(file_path)) +fn parse_binary_file_str<'i>(file_path: &str) -> Result { + Parsed::parse_binary_file(&PathBuf::from(file_path)) } pub fn run_test(base_path: &str, feature: Feature) { @@ -91,7 +88,7 @@ pub fn run_test(base_path: &str, feature: Feature) { assert_eq_pretty!(expr, expected); // Round-trip pretty-printer - let expr: crate::expr::Parsed = + let expr: Parsed = crate::from_str(&expr.to_string(), None).unwrap(); assert_eq!(expr, expected); } @@ -99,7 +96,7 @@ pub fn run_test(base_path: &str, feature: Feature) { let file_path = base_path + ".dhall"; let err = parse_file_str(&file_path).unwrap_err(); match err { - ImportError::ParseError(_) => {} + Error::Parse(_) => {} e => panic!("Expected parse error, got: {:?}", e), } } diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs index 8d1f565..ad4cde6 100644 --- a/dhall/src/traits/deserialize.rs +++ b/dhall/src/traits/deserialize.rs @@ -9,7 +9,7 @@ impl<'a> Deserialize<'a> for Parsed { /// Simply parses the provided string. Ignores the /// provided type. fn from_str(s: &'a str, _ty: Option<&Type>) -> Result { - Ok(Parsed::parse_str(s).map_err(|_| ())?) + Ok(Parsed::parse_str(s)?) } } @@ -17,7 +17,7 @@ impl<'a> Deserialize<'a> for Resolved { /// Parses and resolves the provided string. Ignores the /// provided type. fn from_str(s: &'a str, ty: Option<&Type>) -> Result { - Ok(Parsed::from_str(s, ty)?.resolve().map_err(|_| ())?) + Ok(Parsed::from_str(s, ty)?.resolve()?) } } @@ -25,7 +25,7 @@ impl<'a> Deserialize<'a> for Typed { /// Parses, resolves and typechecks the provided string. fn from_str(s: &'a str, ty: Option<&Type>) -> Result { // TODO: compare with provided type - Ok(Resolved::from_str(s, ty)?.typecheck().map_err(|_| ())?) + Ok(Resolved::from_str(s, ty)?.typecheck()?) } } -- cgit v1.3.1 From 88ac184e7e967c4a5e257c91598f647b8294d71c Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 22:17:13 +0200 Subject: Mild cleanup imports --- dhall/src/imports.rs | 26 ++++++++++++-------------- dhall/src/tests.rs | 8 ++++---- 2 files changed, 16 insertions(+), 18 deletions(-) (limited to 'dhall/src/imports.rs') diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index 3c33b4e..cedc072 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -1,6 +1,3 @@ -// use dhall_core::{Expr, FilePrefix, Import, ImportLocation, ImportMode, X}; -use dhall_core::{Expr, Import, X}; -// use std::path::Path; use crate::error::Error; use crate::expr::*; use dhall_core::*; @@ -27,7 +24,7 @@ pub enum ImportRoot { fn resolve_import( import: &Import, root: &ImportRoot, -) -> Result, ImportError> { +) -> Result { use self::ImportRoot::*; use dhall_core::FilePrefix::*; use dhall_core::ImportLocation::*; @@ -37,11 +34,12 @@ fn resolve_import( match &import.location_hashed.location { Local(prefix, path) => { let path = match prefix { + // TODO: fail gracefully Parent => cwd.parent().unwrap().join(path), Here => cwd.join(path), _ => unimplemented!("{:?}", import), }; - Ok(load_dhall_file(&path, true).map_err(|e| { + Ok(load_import(&path).map_err(|e| { ImportError::Recursive(import.clone(), Box::new(e)) })?) } @@ -49,6 +47,10 @@ fn resolve_import( } } +fn load_import(f: &Path) -> Result { + Ok(Parsed::parse_file(f)?.resolve()?) +} + fn resolve_expr( Parsed(expr, root): Parsed, allow_imports: bool, @@ -56,7 +58,7 @@ fn resolve_expr( let resolve = |import: &Import| -> Result, ImportError> { if allow_imports { let expr = resolve_import(import, &root)?; - Ok(expr.roll()) + Ok(expr.0) } else { Err(ImportError::UnexpectedImport(import.clone())) } @@ -96,12 +98,8 @@ impl Parsed { } } -// Deprecated -pub fn load_dhall_file( - f: &Path, - resolve_imports: bool, -) -> Result, Error> { - let expr = Parsed::parse_file(f)?; - let expr = resolve_expr(expr, resolve_imports)?; - Ok(expr.0.unroll()) +// Deprecated, used for tests only +#[allow(dead_code)] +pub fn load_dhall_file(f: &Path) -> Result, Error> { + Ok(load_import(f)?.0) } diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index 9e78c2f..dede639 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -48,8 +48,8 @@ pub enum Feature { } // Deprecated -fn read_dhall_file<'i>(file_path: &str) -> Result> { - crate::imports::load_dhall_file(&PathBuf::from(file_path), true) +fn read_dhall_file<'i>(file_path: &str) -> Result> { + crate::imports::load_dhall_file(&PathBuf::from(file_path)) } fn parse_file_str<'i>(file_path: &str) -> Result { @@ -134,9 +134,9 @@ pub fn run_test(base_path: &str, feature: Feature) { .spawn(|| { let expr_file_path = base_path.clone() + "A.dhall"; let expected_file_path = base_path + "B.dhall"; - let expr = rc(read_dhall_file(&expr_file_path).unwrap()); + let expr = read_dhall_file(&expr_file_path).unwrap(); let expected = - rc(read_dhall_file(&expected_file_path).unwrap()); + read_dhall_file(&expected_file_path).unwrap(); typecheck::type_of(dhall::subexpr!(expr: expected)) .unwrap(); }) -- cgit v1.3.1 From 7740ec004c6d7e073358bf2be00b6c0006e4dd06 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 10 Apr 2019 22:32:07 +0200 Subject: Allow providing type for typechecking in API --- dhall/src/imports.rs | 6 ------ dhall/src/tests.rs | 23 +++++++++++------------ dhall/src/traits/deserialize.rs | 7 +++++-- dhall/src/typecheck.rs | 5 +++++ 4 files changed, 21 insertions(+), 20 deletions(-) (limited to 'dhall/src/imports.rs') diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index cedc072..7810c55 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -97,9 +97,3 @@ impl Parsed { crate::imports::resolve_expr(self, false) } } - -// Deprecated, used for tests only -#[allow(dead_code)] -pub fn load_dhall_file(f: &Path) -> Result, Error> { - Ok(load_import(f)?.0) -} diff --git a/dhall/src/tests.rs b/dhall/src/tests.rs index dede639..6b1c426 100644 --- a/dhall/src/tests.rs +++ b/dhall/src/tests.rs @@ -31,9 +31,6 @@ macro_rules! make_spec_test { use crate::error::{Error, Result}; use crate::expr::Parsed; -use crate::*; -use dhall_core::*; -use dhall_generator as dhall; use std::path::PathBuf; #[allow(dead_code)] @@ -47,11 +44,6 @@ pub enum Feature { TypeInferenceFailure, } -// Deprecated -fn read_dhall_file<'i>(file_path: &str) -> Result> { - crate::imports::load_dhall_file(&PathBuf::from(file_path)) -} - fn parse_file_str<'i>(file_path: &str) -> Result { Parsed::parse_file(&PathBuf::from(file_path)) } @@ -134,11 +126,18 @@ pub fn run_test(base_path: &str, feature: Feature) { .spawn(|| { let expr_file_path = base_path.clone() + "A.dhall"; let expected_file_path = base_path + "B.dhall"; - let expr = read_dhall_file(&expr_file_path).unwrap(); - let expected = - read_dhall_file(&expected_file_path).unwrap(); - typecheck::type_of(dhall::subexpr!(expr: expected)) + let expr = parse_file_str(&expr_file_path) + .unwrap() + .resolve() .unwrap(); + let expected = parse_file_str(&expected_file_path) + .unwrap() + .resolve() + .unwrap() + .skip_typecheck() + .skip_normalize() + .into_type(); + expr.typecheck_with(&expected).unwrap(); }) .unwrap() .join() diff --git a/dhall/src/traits/deserialize.rs b/dhall/src/traits/deserialize.rs index ad4cde6..5271a65 100644 --- a/dhall/src/traits/deserialize.rs +++ b/dhall/src/traits/deserialize.rs @@ -24,8 +24,11 @@ impl<'a> Deserialize<'a> for Resolved { impl<'a> Deserialize<'a> for Typed { /// Parses, resolves and typechecks the provided string. fn from_str(s: &'a str, ty: Option<&Type>) -> Result { - // TODO: compare with provided type - Ok(Resolved::from_str(s, ty)?.typecheck()?) + let resolved = Resolved::from_str(s, ty)?; + match ty { + None => Ok(resolved.typecheck()?), + Some(t) => Ok(resolved.typecheck_with(t)?), + } } } diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index f51f1b6..9741e65 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -13,6 +13,11 @@ impl Resolved { pub fn typecheck(self) -> Result> { type_of(self.0.clone()) } + pub fn typecheck_with(self, ty: &Type) -> Result> { + let expr: SubExpr<_, _> = self.0.clone(); + let ty: SubExpr<_, _> = ty.as_normalized()?.as_expr().clone(); + type_of(dhall::subexpr!(expr: ty)) + } /// Pretends this expression has been typechecked. Use with care. pub fn skip_typecheck(self) -> Typed { Typed(self.0, UNTYPE) -- cgit v1.3.1