diff options
-rw-r--r-- | dhall/src/expr.rs | 22 | ||||
-rw-r--r-- | dhall/src/imports.rs | 49 | ||||
-rw-r--r-- | dhall/src/lib.rs | 2 | ||||
-rw-r--r-- | dhall/tests/common/mod.rs | 25 |
4 files changed, 66 insertions, 32 deletions
diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 72633ea..ae52e4d 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -1,27 +1,33 @@ -use crate::imports::ImportError; use crate::imports::ImportRoot; use crate::typecheck::TypeError; use dhall_core::*; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq)] pub struct Parsed(pub(crate) SubExpr<X, Import>, pub(crate) ImportRoot); -#[derive(Debug, Clone)] + +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Resolved(pub(crate) SubExpr<X, X>); + #[derive(Debug, Clone)] pub struct Typed(pub(crate) SubExpr<X, X>, Type); + #[derive(Debug, Clone)] pub struct Type(pub(crate) Box<Normalized>); + #[derive(Debug, Clone)] pub struct Normalized(pub(crate) SubExpr<X, X>); -impl Parsed { - pub fn resolve(self) -> Result<Resolved, ImportError> { - crate::imports::resolve_expr(self, true) +impl PartialEq for Parsed { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 } - pub fn resolve_no_imports(self) -> Result<Resolved, ImportError> { - crate::imports::resolve_expr(self, false) +} +impl std::fmt::Display for Parsed { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + self.0.fmt(f) } } + impl Resolved { pub fn typecheck(self) -> Result<Typed, TypeError<X>> { let typ = Type(Box::new(Normalized(crate::typecheck::type_of( diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index bc38bb6..5d94b6a 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -1,6 +1,7 @@ // 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::expr::*; use dhall_core::*; use std::fmt; @@ -12,6 +13,7 @@ use std::path::PathBuf; #[derive(Debug)] pub enum ImportError { ParseError(ParseError), + BinaryDecodeError(DecodeError), IOError(std::io::Error), UnexpectedImportError(Import), } @@ -20,6 +22,11 @@ impl From<ParseError> for ImportError { ImportError::ParseError(e) } } +impl From<DecodeError> for ImportError { + fn from(e: DecodeError) -> Self { + ImportError::BinaryDecodeError(e) + } +} impl From<std::io::Error> for ImportError { fn from(e: std::io::Error) -> Self { ImportError::IOError(e) @@ -30,6 +37,7 @@ impl fmt::Display for ImportError { use self::ImportError::*; match self { ParseError(e) => e.fmt(f), + BinaryDecodeError(_) => unimplemented!(), IOError(e) => e.fmt(f), UnexpectedImportError(e) => e.fmt(f), } @@ -71,7 +79,7 @@ fn resolve_import( } } -pub(crate) fn resolve_expr( +fn resolve_expr( Parsed(expr, root): Parsed, allow_imports: bool, ) -> Result<Resolved, ImportError> { @@ -87,12 +95,35 @@ pub(crate) fn resolve_expr( Ok(Resolved(expr.squash_embed())) } -pub fn load_from_file(f: &Path) -> Result<Parsed, ImportError> { - let mut buffer = String::new(); - File::open(f)?.read_to_string(&mut buffer)?; - let expr = parse_expr(&*buffer)?; - let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); - Ok(Parsed(expr, root)) +impl Parsed { + pub fn load_from_file(f: &Path) -> Result<Parsed, ImportError> { + let mut buffer = String::new(); + File::open(f)?.read_to_string(&mut buffer)?; + let expr = parse_expr(&*buffer)?; + let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); + Ok(Parsed(expr, root)) + } + + pub fn load_from_str(s: &str) -> Result<Parsed, ImportError> { + 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<Parsed, ImportError> { + let mut buffer = Vec::new(); + File::open(f)?.read_to_end(&mut buffer)?; + let expr = crate::binary::decode(&buffer)?; + let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned()); + Ok(Parsed(expr, root)) + } + + pub fn resolve(self) -> Result<Resolved, ImportError> { + crate::imports::resolve_expr(self, true) + } + pub fn resolve_no_imports(self) -> Result<Resolved, ImportError> { + crate::imports::resolve_expr(self, false) + } } // Deprecated @@ -100,7 +131,7 @@ pub fn load_dhall_file( f: &Path, resolve_imports: bool, ) -> Result<Expr<X, X>, ImportError> { - let expr = load_from_file(f)?; + let expr = Parsed::load_from_file(f)?; let expr = resolve_expr(expr, resolve_imports)?; Ok(expr.0.unroll()) } @@ -109,5 +140,5 @@ pub fn load_dhall_file( pub fn load_dhall_file_no_resolve_imports( f: &Path, ) -> Result<ParsedExpr, ImportError> { - Ok(load_from_file(f)?.0) + Ok(Parsed::load_from_file(f)?.0) } diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index fee5ba8..28b43ba 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -9,7 +9,7 @@ mod normalize; pub use crate::normalize::*; -pub mod binary; +mod binary; pub mod imports; mod traits; pub mod typecheck; diff --git a/dhall/tests/common/mod.rs b/dhall/tests/common/mod.rs index 70b7d81..861df63 100644 --- a/dhall/tests/common/mod.rs +++ b/dhall/tests/common/mod.rs @@ -44,20 +44,20 @@ pub enum Feature { TypeInferenceFailure, } -pub fn read_dhall_file<'i>(file_path: &str) -> Result<Expr<X, X>, ImportError> { +fn read_dhall_file<'i>(file_path: &str) -> Result<Expr<X, X>, ImportError> { load_dhall_file(&PathBuf::from(file_path), true) } -pub fn read_dhall_file_no_resolve_imports<'i>( +fn load_from_file_str<'i>( file_path: &str, -) -> Result<dhall_core::ParsedExpr, ImportError> { - load_dhall_file_no_resolve_imports(&PathBuf::from(file_path)) +) -> Result<dhall::Parsed, ImportError> { + Parsed::load_from_file(&PathBuf::from(file_path)) } -pub fn load_from_file_str<'i>( +fn load_from_binary_file_str<'i>( file_path: &str, ) -> Result<dhall::Parsed, ImportError> { - load_from_file(&PathBuf::from(file_path)) + Parsed::load_from_binary_file(&PathBuf::from(file_path)) } pub fn run_test(base_path: &str, feature: Feature) { @@ -77,21 +77,18 @@ pub fn run_test(base_path: &str, feature: Feature) { ParserSuccess => { let expr_file_path = base_path.clone() + "A.dhall"; let expected_file_path = base_path + "B.dhallb"; - let expr = read_dhall_file_no_resolve_imports(&expr_file_path) + let expr = load_from_file_str(&expr_file_path) .map_err(|e| println!("{}", e)) .unwrap(); - use std::fs::File; - use std::io::Read; - let mut file = File::open(expected_file_path).unwrap(); - let mut data = Vec::new(); - file.read_to_end(&mut data).unwrap(); - let expected = dhall::binary::decode(&data).unwrap(); + let expected = load_from_binary_file_str(&expected_file_path) + .map_err(|e| println!("{}", e)) + .unwrap(); assert_eq_pretty!(expr, expected); // Round-trip pretty-printer - let expr = parse_expr(&expr.to_string()).unwrap(); + let expr = Parsed::load_from_str(&expr.to_string()).unwrap(); assert_eq!(expr, expected); } ParserFailure => { |