From 4bebcd96b6e76b9b8ae7877af91d2ae571e617a9 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 7 Apr 2019 16:45:30 +0200 Subject: Restrict public API Closes #20 --- dhall/src/expr.rs | 48 ++++++++++++++++++++++-------------- dhall/src/imports.rs | 15 +---------- dhall/src/lib.rs | 12 ++++----- dhall/src/main.rs | 20 +++++++-------- dhall/src/normalize.rs | 8 ++++-- dhall/src/typecheck.rs | 9 ++++--- dhall/tests/common/mod.rs | 63 +++++++++++++++++++++++++++++++++++------------ 7 files changed, 104 insertions(+), 71 deletions(-) diff --git a/dhall/src/expr.rs b/dhall/src/expr.rs index 555db2f..7baf628 100644 --- a/dhall/src/expr.rs +++ b/dhall/src/expr.rs @@ -1,34 +1,46 @@ use crate::imports::ImportRoot; use dhall_core::*; +macro_rules! derive_other_traits { + ($ty:ident) => { + impl std::cmp::PartialEq for $ty { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } + } + + impl std::fmt::Display for $ty { + fn fmt( + &self, + f: &mut std::fmt::Formatter, + ) -> Result<(), std::fmt::Error> { + self.0.fmt(f) + } + } + }; +} + #[derive(Debug, Clone, Eq)] pub struct Parsed(pub(crate) SubExpr, pub(crate) ImportRoot); +derive_other_traits!(Parsed); -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, Eq)] pub struct Resolved(pub(crate) SubExpr); +derive_other_traits!(Resolved); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Eq)] pub struct Typed(pub(crate) SubExpr, pub(crate) Type); +derive_other_traits!(Typed); + +#[derive(Debug, Clone, Eq)] +pub struct Normalized(pub(crate) SubExpr, pub(crate) Type); +derive_other_traits!(Normalized); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Type(pub(crate) TypeInternal); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum TypeInternal { Expr(Box), Untyped, } - -#[derive(Debug, Clone)] -pub struct Normalized(pub(crate) SubExpr, pub(crate) Type); - -impl PartialEq for Parsed { - fn eq(&self, other: &Self) -> bool { - self.0 == other.0 - } -} -impl std::fmt::Display for Parsed { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - self.0.fmt(f) - } -} diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs index 5d94b6a..fdde8c3 100644 --- a/dhall/src/imports.rs +++ b/dhall/src/imports.rs @@ -44,12 +44,6 @@ impl fmt::Display for ImportError { } } -// Deprecated -pub fn panic_imports(expr: &Expr) -> Expr { - let no_import = |i: &Import| -> X { panic!("ahhh import: {:?}", i) }; - expr.map_embed(&no_import) -} - /// A root from which to resolve relative imports. #[derive(Debug, Clone, PartialEq, Eq)] pub enum ImportRoot { @@ -121,7 +115,7 @@ impl Parsed { pub fn resolve(self) -> Result { crate::imports::resolve_expr(self, true) } - pub fn resolve_no_imports(self) -> Result { + pub fn skip_resolve(self) -> Result { crate::imports::resolve_expr(self, false) } } @@ -135,10 +129,3 @@ pub fn load_dhall_file( let expr = resolve_expr(expr, resolve_imports)?; Ok(expr.0.unroll()) } - -// Deprecated -pub fn load_dhall_file_no_resolve_imports( - f: &Path, -) -> Result { - Ok(Parsed::load_from_file(f)?.0) -} diff --git a/dhall/src/lib.rs b/dhall/src/lib.rs index 28b43ba..f00e5b6 100644 --- a/dhall/src/lib.rs +++ b/dhall/src/lib.rs @@ -7,16 +7,14 @@ clippy::many_single_char_names )] -mod normalize; -pub use crate::normalize::*; mod binary; -pub mod imports; -mod traits; +mod imports; +mod normalize; +pub mod traits; pub mod typecheck; -pub use crate::imports::*; -pub use crate::traits::*; +pub use crate::imports::{load_dhall_file, ImportError}; +pub use crate::traits::StaticType; pub use dhall_generator::expr; pub use dhall_generator::subexpr; pub use dhall_generator::StaticType; pub mod expr; -pub use crate::expr::*; diff --git a/dhall/src/main.rs b/dhall/src/main.rs index 77f558c..2881d5a 100644 --- a/dhall/src/main.rs +++ b/dhall/src/main.rs @@ -2,9 +2,6 @@ use std::error::Error; use std::io::{self, Read}; use term_painter::ToStyle; -use dhall::*; -use dhall_core::*; - const ERROR_STYLE: term_painter::Color = term_painter::Color::Red; const BOLD: term_painter::Attr = term_painter::Attr::Bold; @@ -57,17 +54,19 @@ fn print_error(message: &str, source: &str, start: usize, end: usize) { fn main() { let mut buffer = String::new(); io::stdin().read_to_string(&mut buffer).unwrap(); - let expr = match parse_expr(&buffer) { - Ok(e) => e, + + let expr = match dhall::expr::Parsed::load_from_str(&buffer) { + Ok(expr) => expr, Err(e) => { print_error(&format!("Parse error {}", e), &buffer, 0, 0); return; } }; - let expr: SubExpr<_, _> = rc(imports::panic_imports(expr.as_ref())); + let expr = expr.resolve().unwrap(); - let type_expr = match typecheck::type_of(expr.clone()) { + let expr = match expr.typecheck() { + Ok(expr) => expr, Err(e) => { let explain = ::std::env::args().any(|s| s == "--explain"); if !explain { @@ -84,10 +83,9 @@ fn main() { // FIXME Print source position return; } - Ok(type_expr) => type_expr, }; - println!("{}", type_expr); - println!(); - println!("{}", normalize(expr)); + let expr = expr.normalize(); + + println!("{}", expr); } diff --git a/dhall/src/normalize.rs b/dhall/src/normalize.rs index f9633fb..c07d3cb 100644 --- a/dhall/src/normalize.rs +++ b/dhall/src/normalize.rs @@ -8,6 +8,10 @@ impl Typed { pub fn normalize(self) -> Normalized { Normalized(normalize(self.0), self.1) } + /// Pretends this expression is normalized. Use with care. + pub fn skip_normalize(self) -> Normalized { + Normalized(self.0, self.1) + } } fn apply_builtin(b: Builtin, args: &Vec>) -> WhatNext @@ -209,7 +213,7 @@ enum WhatNext<'a, S, A> { DoneAsIs, } -pub fn normalize_ref(expr: &Expr) -> Expr +fn normalize_ref(expr: &Expr) -> Expr where S: fmt::Debug + Clone, A: fmt::Debug + Clone, @@ -313,7 +317,7 @@ where /// However, `normalize` will not fail if the expression is ill-typed and will /// leave ill-typed sub-expressions unevaluated. /// -pub fn normalize(e: SubExpr) -> SubExpr +fn normalize(e: SubExpr) -> SubExpr where S: fmt::Debug + Clone, A: fmt::Debug + Clone, diff --git a/dhall/src/typecheck.rs b/dhall/src/typecheck.rs index a0782f8..babfad0 100644 --- a/dhall/src/typecheck.rs +++ b/dhall/src/typecheck.rs @@ -11,8 +11,11 @@ use self::TypeMessage::*; impl Resolved { pub fn typecheck(self) -> Result> { - let typ = crate::typecheck::type_of_(self.0.clone())?; - Ok(typ) + type_of_(self.0.clone()) + } + /// Pretends this expression has been typechecked. Use with care. + pub fn skip_typecheck(self) -> Typed { + Typed(self.0, UNTYPE) } } impl Typed { @@ -63,7 +66,7 @@ impl Normalized { } impl Type { #[inline(always)] - fn as_normalized(&self) -> Result<&Normalized, TypeError> { + pub fn as_normalized(&self) -> Result<&Normalized, TypeError> { use TypeInternal::*; match &self.0 { Expr(e) => Ok(e), diff --git a/dhall/tests/common/mod.rs b/dhall/tests/common/mod.rs index fc5aa5b..5f16d2c 100644 --- a/dhall/tests/common/mod.rs +++ b/dhall/tests/common/mod.rs @@ -44,20 +44,21 @@ pub enum Feature { TypeInferenceFailure, } +// Deprecated fn read_dhall_file<'i>(file_path: &str) -> Result, ImportError> { - load_dhall_file(&PathBuf::from(file_path), true) + dhall::load_dhall_file(&PathBuf::from(file_path), true) } fn load_from_file_str<'i>( file_path: &str, -) -> Result { - Parsed::load_from_file(&PathBuf::from(file_path)) +) -> Result { + dhall::expr::Parsed::load_from_file(&PathBuf::from(file_path)) } fn load_from_binary_file_str<'i>( file_path: &str, -) -> Result { - Parsed::load_from_binary_file(&PathBuf::from(file_path)) +) -> Result { + dhall::expr::Parsed::load_from_binary_file(&PathBuf::from(file_path)) } pub fn run_test(base_path: &str, feature: Feature) { @@ -88,7 +89,8 @@ pub fn run_test(base_path: &str, feature: Feature) { assert_eq_pretty!(expr, expected); // Round-trip pretty-printer - let expr = Parsed::load_from_str(&expr.to_string()).unwrap(); + let expr = + dhall::expr::Parsed::load_from_str(&expr.to_string()).unwrap(); assert_eq!(expr, expected); } ParserFailure => { @@ -102,15 +104,29 @@ pub fn run_test(base_path: &str, feature: Feature) { Normalization => { 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 expected = rc(read_dhall_file(&expected_file_path).unwrap()); + let expr = load_from_file_str(&expr_file_path) + .unwrap() + .resolve() + .unwrap() + .skip_typecheck() + .normalize(); + let expected = load_from_file_str(&expected_file_path) + .unwrap() + .resolve() + .unwrap() + .skip_typecheck() + .normalize(); - assert_eq_display!(normalize(expr), normalize(expected)); + assert_eq_display!(expr, expected); } TypecheckFailure => { let file_path = base_path + ".dhall"; - let expr = rc(read_dhall_file(&file_path).unwrap()); - typecheck::type_of(expr).unwrap_err(); + load_from_file_str(&file_path) + .unwrap() + .skip_resolve() + .unwrap() + .typecheck() + .unwrap_err(); } TypecheckSuccess => { // Many tests stack overflow in debug mode @@ -131,15 +147,30 @@ pub fn run_test(base_path: &str, feature: Feature) { } TypeInferenceFailure => { let file_path = base_path + ".dhall"; - let expr = rc(read_dhall_file(&file_path).unwrap()); - typecheck::type_of(expr).unwrap_err(); + load_from_file_str(&file_path) + .unwrap() + .skip_resolve() + .unwrap() + .typecheck() + .unwrap_err(); } TypeInferenceSuccess => { 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 expected = rc(read_dhall_file(&expected_file_path).unwrap()); - assert_eq_display!(typecheck::type_of(expr).unwrap(), expected); + let expr = load_from_file_str(&expr_file_path) + .unwrap() + .skip_resolve() + .unwrap() + .typecheck() + .unwrap(); + let ty = expr.get_type().as_normalized().unwrap(); + let expected = load_from_file_str(&expected_file_path) + .unwrap() + .skip_resolve() + .unwrap() + .skip_typecheck() + .skip_normalize(); + assert_eq_display!(ty, &expected); } } } -- cgit v1.2.3