difftreelog
feat(evaluator) eval methods in EvaluationState
in: master
1 file changed
crates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth9mod obj;9mod obj;10mod val;10mod val;111112use closure::closure;12pub use ctx::*;13pub use ctx::*;13pub use dynamic::*;14pub use dynamic::*;14pub use error::*;15pub use error::*;35 dyn Fn(Context, LocExpr) -> Val36 dyn Fn(Context, LocExpr) -> Val36);37);373838#[derive(Default, Clone)]39#[derive(Default)]39pub struct EvaluationState {40pub struct EvaluationStateInternals {40 /// Used for stack-overflows and stacktraces41 /// Used for stack-overflows and stacktraces41 pub stack: Rc<RefCell<Vec<(LocExpr, String)>>>,42 stack: RefCell<Vec<(LocExpr, String)>>,42 /// Contains file source codes and evaluated results for imports and pretty printing stacktraces43 /// Contains file source codes and evaluated results for imports and pretty printing stacktraces43 pub files: Rc<RefCell<HashMap<String, (String, Option<Val>)>>>,44 files: RefCell<HashMap<String, (String, LocExpr, Option<Val>)>>,45 globals: RefCell<HashMap<String, Val>>,44}46}4748#[derive(Default, Clone)]49pub struct EvaluationState(Rc<EvaluationStateInternals>);45impl EvaluationState {50impl EvaluationState {51 pub fn add_file(&self, name: String, code: String) -> Result<(), Box<dyn std::error::Error>> {52 self.0.files.borrow_mut().insert(53 name.clone(),54 (55 code.clone(),56 parse(57 &code,58 &ParserSettings {59 file_name: name.clone(),60 loc_data: true,61 },62 )?,63 None,64 ),65 );6667 Ok(())68 }69 pub fn evaluate_file(&self, name: &str) -> Result<Val, Box<dyn std::error::Error>> {70 let expr: LocExpr = {71 let ro_map = self.0.files.borrow();72 let value = ro_map73 .get(name)74 .unwrap_or_else(|| panic!("file not added: {:?}", name));75 if value.2.is_some() {76 return Ok(value.2.clone().unwrap());77 }78 value.1.clone()79 };80 let value = evaluate(self.create_default_context(), self.clone(), &expr);81 {82 self.083 .files84 .borrow_mut()85 .get_mut(name)86 .unwrap()87 .288 .replace(value.clone());89 }90 Ok(value)91 }9293 pub fn parse_evaluate_raw(&self, code: &str) -> Val {94 let parsed = parse(95 &code,96 &ParserSettings {97 file_name: "raw.jsonnet".to_owned(),98 loc_data: true,99 },100 );101 evaluate(102 self.create_default_context(),103 self.clone(),104 &parsed.unwrap(),105 )106 }107108 pub fn add_stdlib(&self) {109 use jsonnet_stdlib::STDLIB_STR;110 self.add_file("std.jsonnet".to_owned(), STDLIB_STR.to_owned())111 .unwrap();112 let val = self.evaluate_file("std.jsonnet").unwrap();113 self.0.globals.borrow_mut().insert("std".to_owned(), val);114 }115116 pub fn create_default_context(&self) -> Context {117 let globals = self.0.globals.borrow();118 let mut new_bindings: HashMap<String, LazyBinding> = HashMap::new();119 for (name, value) in globals.iter() {120 new_bindings.insert(121 name.clone(),122 lazy_binding!(123 closure!(clone value, |_self, _super_obj| lazy_val!(closure!(clone value, ||value.clone())))124 ),125 );126 }127 Context::new().extend(new_bindings, None, None, None)128 }12946 pub fn push<T>(&self, e: LocExpr, comment: String, f: impl FnOnce() -> T) -> T {130 pub fn push<T>(&self, e: LocExpr, comment: String, f: impl FnOnce() -> T) -> T {47 self.stack.borrow_mut().push((e, comment));131 self.0.stack.borrow_mut().push((e, comment));48 let result = f();132 let result = f();49 self.stack.borrow_mut().pop();133 self.0.stack.borrow_mut().pop();50 result134 result51 }135 }52 pub fn print_stack_trace(&self) {136 pub fn print_stack_trace(&self) {53 for e in self137 for e in self.stack_trace() {54 .stack55 .borrow()56 .iter()57 .rev()58 .map(|(loc, comment)| loc.1.clone().map(|v| (v, comment.clone())))59 .flatten()60 {61 println!("{:?} - {:?}", e.0, e.1)138 println!("{:?} - {:?}", e.0, e.1)62 }139 }63 }140 }64 pub fn stack_trace(&self) -> Vec<(LocExpr, String)> {141 pub fn stack_trace(&self) -> Vec<(LocExpr, String)> {65 self.stack142 self.0143 .stack66 .borrow()144 .borrow()67 .iter()145 .iter()93 );171 );94 }172 }173174 #[test]175 fn eval_state_standard() {176 let state = EvaluationState::default();177 state.add_stdlib();178 assert_eq!(179 state.parse_evaluate_raw(r#"std.base64("test") == "dGVzdA==""#),180 Val::Bool(true)181 );182 }9518396 macro_rules! eval {184 macro_rules! eval {97 ($str: expr) => {185 ($str: expr) => {359447360 #[test]448 #[test]361 fn json() {449 fn json() {362 println!("{:?}", eval_stdlib!(r#"std.manifestJsonEx({a:3, b:4, c:6},"")"#));450 assert_json_stdlib!(451 r#"std.manifestJsonEx({a:3, b:4, c:6},"")"#,452 r#""{\n"a": 3,\n"b": 4,\n"c": 6\n}""#453 );363 }454 }364455365 #[test]456 #[test]366 fn test() {457 fn test() {367 assert_json_stdlib!(r#"[[a, b] for a in [1,2,3] for b in [4,5,6]]"#, "");458 assert_json_stdlib!(459 r#"[[a, b] for a in [1,2,3] for b in [4,5,6]]"#,460 "[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]"461 );368 }462 }369463