difftreelog
docs(evaluator) document public api
in: master
2 files changed
crates/jrsonnet-evaluator/src/import.rsdiffbeforeafterboth1use crate::create_error_result;2use crate::{3 create_error,4 error::{Error, Result},5};6use fs::File;7use std::fs;8use std::io::Read;9use std::{any::Any, cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};1011pub trait ImportResolver {12 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>>;13 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>>;14 unsafe fn as_any(&self) -> &dyn Any;15}1617pub struct DummyImportResolver;18impl ImportResolver for DummyImportResolver {19 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {20 create_error_result(Error::ImportNotSupported(from.clone(), path.clone()))21 }22 fn load_file_contents(&self, _resolved: &PathBuf) -> Result<Rc<str>> {23 // Can be only caused by library direct consumer, not by supplied jsonnet24 panic!("dummy resolver can't load any file")25 }26 unsafe fn as_any(&self) -> &dyn Any {27 panic!("this resolver can't be used as any")28 }29}30impl Default for Box<dyn ImportResolver> {31 fn default() -> Self {32 Box::new(DummyImportResolver)33 }34}3536pub struct FileImportResolver {37 pub library_paths: Vec<PathBuf>,38}39impl ImportResolver for FileImportResolver {40 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {41 let mut new_path = from.clone();42 new_path.push(path);43 if new_path.exists() {44 Ok(Rc::new(new_path))45 } else {46 for library_path in self.library_paths.iter() {47 let mut cloned = library_path.clone();48 cloned.push(path);49 if cloned.exists() {50 return Ok(Rc::new(cloned));51 }52 }53 create_error_result(Error::ImportFileNotFound(from.clone(), path.clone()))54 }55 }56 fn load_file_contents(&self, id: &PathBuf) -> Result<Rc<str>> {57 let mut file =58 File::open(id).map_err(|_e| create_error(Error::ResolvedFileNotFound(id.clone())))?;59 let mut out = String::new();60 file.read_to_string(&mut out)61 .map_err(|_e| create_error(Error::ImportBadFileUtf8(id.clone())))?;62 Ok(out.into())63 }64 unsafe fn as_any(&self) -> &dyn Any {65 panic!("this resolver can't be used as any")66 }67}6869type ResolutionData = (PathBuf, PathBuf);70pub struct CachingImportResolver {71 resolution_cache: RefCell<HashMap<ResolutionData, Result<Rc<PathBuf>>>>,72 loading_cache: RefCell<HashMap<PathBuf, Result<Rc<str>>>>,73 inner: Box<dyn ImportResolver>,74}75impl ImportResolver for CachingImportResolver {76 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {77 self.resolution_cache78 .borrow_mut()79 .entry((from.clone(), path.clone()))80 .or_insert_with(|| self.inner.resolve_file(from, path))81 .clone()82 }83 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>> {84 self.loading_cache85 .borrow_mut()86 .entry(resolved.clone())87 .or_insert_with(|| self.inner.load_file_contents(resolved))88 .clone()89 }90 unsafe fn as_any(&self) -> &dyn Any {91 panic!("this resolver can't be used as any")92 }93}1use crate::create_error_result;2use crate::{3 create_error,4 error::{Error, Result},5};6use fs::File;7use std::fs;8use std::io::Read;9use std::{any::Any, cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};1011/// Implements file resolution logic for `import` and `importStr`12pub trait ImportResolver {13 /// Resolve real file path, i.e14 /// `(/home/user/manifests, b.libsonnet)` can resolve to both `/home/user/manifests/b.libsonnet` and to `/home/user/vendor/b.libsonnet`15 /// (Where vendor is a library path)16 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>>;17 /// Reads file from filesystem, should be used only with path received from `resolve_file`18 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>>;19 /// # Safety20 ///21 /// For use in bindings, do not try to use it elsewhere22 /// Implementations, which are not intended to be23 /// used in bindings, should panic in this method24 unsafe fn as_any(&self) -> &dyn Any;25}2627/// Dummy resolver, can't resolve/load any file28pub struct DummyImportResolver;29impl ImportResolver for DummyImportResolver {30 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {31 create_error_result(Error::ImportNotSupported(from.clone(), path.clone()))32 }33 fn load_file_contents(&self, _resolved: &PathBuf) -> Result<Rc<str>> {34 // Can be only caused by library direct consumer, not by supplied jsonnet35 panic!("dummy resolver can't load any file")36 }37 unsafe fn as_any(&self) -> &dyn Any {38 panic!("this resolver can't be used as any")39 }40}41impl Default for Box<dyn ImportResolver> {42 fn default() -> Self {43 Box::new(DummyImportResolver)44 }45}4647/// File resolver, can load file from both FS and library paths48#[derive(Default)]49pub struct FileImportResolver {50 /// Library directories to search for file51 /// In original jsonnet referred as jpath52 pub library_paths: Vec<PathBuf>,53}54impl ImportResolver for FileImportResolver {55 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {56 let mut new_path = from.clone();57 new_path.push(path);58 if new_path.exists() {59 Ok(Rc::new(new_path))60 } else {61 for library_path in self.library_paths.iter() {62 let mut cloned = library_path.clone();63 cloned.push(path);64 if cloned.exists() {65 return Ok(Rc::new(cloned));66 }67 }68 create_error_result(Error::ImportFileNotFound(from.clone(), path.clone()))69 }70 }71 fn load_file_contents(&self, id: &PathBuf) -> Result<Rc<str>> {72 let mut file =73 File::open(id).map_err(|_e| create_error(Error::ResolvedFileNotFound(id.clone())))?;74 let mut out = String::new();75 file.read_to_string(&mut out)76 .map_err(|_e| create_error(Error::ImportBadFileUtf8(id.clone())))?;77 Ok(out.into())78 }79 unsafe fn as_any(&self) -> &dyn Any {80 panic!("this resolver can't be used as any")81 }82}8384type ResolutionData = (PathBuf, PathBuf);8586/// Caches results of underlying resolver implementation87pub struct CachingImportResolver {88 resolution_cache: RefCell<HashMap<ResolutionData, Result<Rc<PathBuf>>>>,89 loading_cache: RefCell<HashMap<PathBuf, Result<Rc<str>>>>,90 inner: Box<dyn ImportResolver>,91}92impl ImportResolver for CachingImportResolver {93 fn resolve_file(&self, from: &PathBuf, path: &PathBuf) -> Result<Rc<PathBuf>> {94 self.resolution_cache95 .borrow_mut()96 .entry((from.clone(), path.clone()))97 .or_insert_with(|| self.inner.resolve_file(from, path))98 .clone()99 }100 fn load_file_contents(&self, resolved: &PathBuf) -> Result<Rc<str>> {101 self.loading_cache102 .borrow_mut()103 .entry(resolved.clone())104 .or_insert_with(|| self.inner.load_file_contents(resolved))105 .clone()106 }107 unsafe fn as_any(&self) -> &dyn Any {108 panic!("this resolver can't be used as any")109 }110}crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -311,6 +311,7 @@
Context::new().extend_unbound(new_bindings, None, None, None)
}
+ /// Executes code, creating new stack frame
pub fn push<T>(
&self,
e: ExprLocation,
@@ -332,11 +333,8 @@
self.data_mut().stack.pop();
result
}
- pub fn print_stack_trace(&self) {
- for e in self.stack_trace().0 {
- println!("{:?} - {:?}", e.0, e.1)
- }
- }
+
+ /// Returns current stack trace
pub fn stack_trace(&self) -> StackTrace {
StackTrace(
self.data()
@@ -348,10 +346,13 @@
.collect(),
)
}
+
+ /// Creates error with stack trace
pub fn error(&self, err: Error) -> LocError {
LocError(err, self.stack_trace())
}
+ /// Runs passed function in state (required, if function needs to modify stack trace)
pub fn run_in_state<T>(&self, f: impl FnOnce() -> T) -> T {
EVAL_STATE.with(|v| {
let has_state = v.borrow().is_some();
@@ -386,7 +387,6 @@
ExprLocation(Rc::new(PathBuf::from("test2.jsonnet")), 30, 40),
"inner".to_owned(),
|| {
- state.print_stack_trace();
Ok(())
},
)?;