--- a/bindings/jsonnet/src/lib.rs +++ b/bindings/jsonnet/src/lib.rs @@ -306,10 +306,42 @@ } }) } + +/// # Safety +/// +/// This function is safe, if received v is a pointer to normal C string #[no_mangle] -pub extern "C" fn jsonnet_evaluate_snippet() { - todo!() +pub unsafe extern "C" fn jsonnet_evaluate_snippet( + vm: &EvaluationState, + filename: *const c_char, + snippet: *const c_char, + error: &mut c_int, +) -> *const c_char { + vm.run_in_state(|| { + use std::fmt::Write; + let filename = CStr::from_ptr(filename); + let snippet = CStr::from_ptr(snippet); + match vm.evaluate_snippet_to_json( + &PathBuf::from(filename.to_str().unwrap()), + &snippet.to_str().unwrap(), + ) { + Ok(v) => { + *error = 0; + CString::new(&*v as &str).unwrap().into_raw() + } + Err(e) => { + *error = 1; + let mut out = String::new(); + writeln!(out, "{:?}", e.0).unwrap(); + for i in (e.1).0.iter() { + writeln!(out, "{:?} ---- {}", i.0, i.1).unwrap(); + } + CString::new(&out as &str).unwrap().into_raw() + } + } + }) } + #[no_mangle] pub extern "C" fn jsonnet_evaluate_file_multi() { todo!() --- a/crates/jrsonnet-evaluator/src/lib.rs +++ b/crates/jrsonnet-evaluator/src/lib.rs @@ -140,6 +140,14 @@ ) -> std::result::Result, LocError> { self.import_file(&PathBuf::new(), &path).and_then(|v|v.into_json(4)) } + pub fn evaluate_snippet_to_json( + &self, + path: &PathBuf, + snippet: &str, + ) -> std::result::Result, LocError> { + self.parse_evaluate_raw_with_source(Rc::new(path.clone()), snippet).and_then(|v|v.into_json(4)) + } + pub fn add_file( &self, name: Rc, @@ -228,17 +236,20 @@ Ok(self.data().str_files.get(&path).cloned().unwrap()) } - pub fn parse_evaluate_raw(&self, code: &str) -> Result { + pub fn parse_evaluate_raw_with_source(&self, source: Rc, code: &str) -> Result { let parsed = parse( &code, &ParserSettings { - file_name: Rc::new(PathBuf::from("raw.jsonnet")), + file_name: source, loc_data: true, }, ) .unwrap(); self.evaluate_raw(parsed) } + pub fn parse_evaluate_raw(&self, code: &str) -> Result { + self.parse_evaluate_raw_with_source(Rc::new(PathBuf::from("raw.jsonnet")), code) + } pub fn evaluate_raw(&self, code: LocExpr) -> Result { self.run_in_state(|| evaluate(self.create_default_context()?, &code))