difftreelog
feat import support
in: master
3 files changed
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -1,7 +1,7 @@
pub mod location;
use clap::Clap;
-use jsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val};
+use jsonnet_evaluator::{EvaluationSettings, EvaluationState, LocError, StackTrace, Val};
use location::{offset_to_location, CodeLocation};
use std::env::current_dir;
use std::{path::PathBuf, str::FromStr};
@@ -111,7 +111,10 @@
fn main() {
let opts: Opts = Opts::parse();
- let evaluator = jsonnet_evaluator::EvaluationState::default();
+ let evaluator = jsonnet_evaluator::EvaluationState::new(EvaluationSettings {
+ import_resolver: Box::new(|path| String::from_utf8(std::fs::read(path).unwrap()).unwrap()),
+ ..Default::default()
+ });
if !opts.no_stdlib {
evaluator.with_stdlib();
}
crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -1,5 +1,5 @@
use crate::{
- binding, context_creator, create_error, future_wrapper, lazy_val, push, Context,
+ binding, context_creator, create_error, future_wrapper, lazy_val, push, with_state, Context,
ContextCreator, FuncDesc, LazyBinding, ObjMember, ObjValue, Result, Val,
};
use closure::closure;
@@ -607,6 +607,16 @@
}
}
}
+ Import(path) => {
+ let mut lib_path = loc
+ .clone()
+ .expect("imports can't be used without loc_data")
+ .0
+ .clone();
+ lib_path.pop();
+ lib_path.push(path);
+ with_state(|s| s.import_file(&lib_path))?
+ }
_ => panic!(
"evaluation not implemented: {:?}",
LocExpr(expr.clone(), loc.clone())
crates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth50}50}515152pub struct EvaluationSettings {52pub struct EvaluationSettings {53 max_stack_frames: usize,53 pub max_stack_frames: usize,54 max_stack_trace_size: usize,54 pub max_stack_trace_size: usize,55 pub import_resolver: Box<dyn Fn(&PathBuf) -> String>,55}56}56impl Default for EvaluationSettings {57impl Default for EvaluationSettings {57 fn default() -> Self {58 fn default() -> Self {58 EvaluationSettings {59 EvaluationSettings {59 max_stack_frames: 200,60 max_stack_frames: 200,60 max_stack_trace_size: 20,61 max_stack_trace_size: 20,62 import_resolver: Box::new(|path| {63 panic!("default EvaluationSettings have no support for import resolution, can't import {:?}", path)64 }),61 }65 }62 }66 }63}67}102#[derive(Default, Clone)]106#[derive(Default, Clone)]103pub struct EvaluationState(Rc<EvaluationStateInternals>);107pub struct EvaluationState(Rc<EvaluationStateInternals>);104impl EvaluationState {108impl EvaluationState {109 pub fn new(settings: EvaluationSettings) -> Self {110 EvaluationState(Rc::new(EvaluationStateInternals {111 settings,112 ..Default::default()113 }))114 }105 pub fn add_file(&self, name: PathBuf, code: String) -> std::result::Result<(), ParseError> {115 pub fn add_file(&self, name: PathBuf, code: String) -> std::result::Result<(), ParseError> {106 self.0.files.borrow_mut().insert(116 self.0.files.borrow_mut().insert(107 name.clone(),117 name.clone(),137 let ro_map = self.0.files.borrow();147 let ro_map = self.0.files.borrow();138 ro_map.get(name).map(|value| value.0.clone())148 ro_map.get(name).map(|value| value.0.clone())139 }149 }140 pub fn evaluate_file(&self, name: &PathBuf) -> Result<Val> {150 pub fn evaluate_file(&self, name: &PathBuf) -> Result<Val> {151 self.begin_state();152 let value = self.evaluate_file_in_current_state(name)?;153 self.end_state();154 Ok(value)155 }141 self.begin_state();156 pub(crate) fn evaluate_file_in_current_state(&self, name: &PathBuf) -> Result<Val> {142 let expr: LocExpr = {157 let expr: LocExpr = {143 let ro_map = self.0.files.borrow();158 let ro_map = self.0.files.borrow();144 let value = ro_map159 let value = ro_map159 .2174 .2160 .replace(value.clone());175 .replace(value.clone());161 }176 }177 Ok(value)178 }179 pub(crate) fn import_file(&self, path: &PathBuf) -> Result<Val> {180 if !self.0.files.borrow().contains_key(path) {181 let file_str = (self.0.settings.import_resolver)(path);162 self.end_state();182 self.add_file(path.clone(), file_str).unwrap();183 }163 Ok(value)184 self.evaluate_file_in_current_state(path)164 }185 }165186166 pub fn parse_evaluate_raw(&self, code: &str) -> Result<Val> {187 pub fn parse_evaluate_raw(&self, code: &str) -> Result<Val> {167 let parsed = parse(188 let parsed = parse(