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 --- 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 ++--- 5 files changed, 51 insertions(+), 56 deletions(-) (limited to 'dhall') 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.2.3