summaryrefslogtreecommitdiff
path: root/dhall/src/imports.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dhall/src/imports.rs')
-rw-r--r--dhall/src/imports.rs127
1 files changed, 81 insertions, 46 deletions
diff --git a/dhall/src/imports.rs b/dhall/src/imports.rs
index 96268ca..fdde8c3 100644
--- a/dhall/src/imports.rs
+++ b/dhall/src/imports.rs
@@ -1,6 +1,8 @@
// 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;
use std::fs::File;
@@ -8,9 +10,38 @@ use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
-pub fn panic_imports<S: Clone>(expr: &Expr<S, Import>) -> Expr<S, X> {
- let no_import = |i: &Import| -> X { panic!("ahhh import: {:?}", i) };
- expr.map_embed(&no_import)
+#[derive(Debug)]
+pub enum ImportError {
+ ParseError(ParseError),
+ BinaryDecodeError(DecodeError),
+ IOError(std::io::Error),
+ UnexpectedImportError(Import),
+}
+impl From<ParseError> for ImportError {
+ fn from(e: ParseError) -> Self {
+ 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)
+ }
+}
+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),
+ }
+ }
}
/// A root from which to resolve relative imports.
@@ -22,7 +53,7 @@ pub enum ImportRoot {
fn resolve_import(
import: &Import,
root: &ImportRoot,
-) -> Result<Expr<X, X>, DhallError> {
+) -> Result<Expr<X, X>, ImportError> {
use self::ImportRoot::*;
use dhall_core::FilePrefix::*;
use dhall_core::ImportLocation::*;
@@ -42,55 +73,59 @@ fn resolve_import(
}
}
-#[derive(Debug)]
-pub enum DhallError {
- ParseError(ParseError),
- IOError(std::io::Error),
+fn resolve_expr(
+ Parsed(expr, root): Parsed,
+ allow_imports: bool,
+) -> Result<Resolved, ImportError> {
+ let resolve = |import: &Import| -> Result<SubExpr<X, X>, ImportError> {
+ if allow_imports {
+ let expr = resolve_import(import, &root)?;
+ Ok(expr.roll())
+ } else {
+ Err(ImportError::UnexpectedImportError(import.clone()))
+ }
+ };
+ let expr = expr.as_ref().traverse_embed(&resolve)?;
+ Ok(Resolved(expr.squash_embed()))
}
-impl From<ParseError> for DhallError {
- fn from(e: ParseError) -> Self {
- DhallError::ParseError(e)
+
+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))
}
-}
-impl From<std::io::Error> for DhallError {
- fn from(e: std::io::Error) -> Self {
- DhallError::IOError(e)
+
+ 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))
}
-}
-impl fmt::Display for DhallError {
- fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- use self::DhallError::*;
- match self {
- ParseError(e) => e.fmt(f),
- IOError(e) => e.fmt(f),
- }
+
+ 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 skip_resolve(self) -> Result<Resolved, ImportError> {
+ crate::imports::resolve_expr(self, false)
}
}
+// Deprecated
pub fn load_dhall_file(
f: &Path,
resolve_imports: bool,
-) -> Result<Expr<X, X>, DhallError> {
- let mut buffer = String::new();
- File::open(f)?.read_to_string(&mut buffer)?;
- let expr = parse_expr(&*buffer)?;
- let expr = if resolve_imports {
- let root = ImportRoot::LocalDir(f.parent().unwrap().to_owned());
- let resolve = |import: &Import| -> Expr<X, X> {
- resolve_import(import, &root).unwrap()
- };
- expr.as_ref().map_embed(&resolve).squash_embed()
- } else {
- panic_imports(expr.as_ref())
- };
- Ok(expr)
-}
-
-pub fn load_dhall_file_no_resolve_imports(
- f: &Path,
-) -> Result<ParsedExpr, DhallError> {
- let mut buffer = String::new();
- File::open(f)?.read_to_string(&mut buffer)?;
- let expr = parse_expr(&*buffer)?;
- Ok(expr)
+) -> Result<Expr<X, X>, ImportError> {
+ let expr = Parsed::load_from_file(f)?;
+ let expr = resolve_expr(expr, resolve_imports)?;
+ Ok(expr.0.unroll())
}