difftreelog
feat native callbacks
in: master
10 files changed
bindings/jsonnet/src/interop.rsdiffbeforeafterboth1//! Jrsonnet specific additional binding helpers1//! Jrsonnet specific additional binding helpers223use crate::import::jsonnet_import_callback;3use crate::{import::jsonnet_import_callback, native::jsonnet_native_callback};4use jrsonnet_evaluator::EvaluationState;4use jrsonnet_evaluator::{EvaluationState, Val};5use std::{5use std::{6 ffi::c_void,6 ffi::c_void,7 os::raw::{c_char, c_int},7 os::raw::{c_char, c_int},16 success: &mut c_int,16 success: &mut c_int,17 ) -> *const c_char;17 ) -> *const c_char;1819 #[allow(improper_ctypes)]20 pub fn _jrsonnet_static_native_callback(21 ctx: *const c_void,22 argv: *const *const Val,23 success: *mut c_int,24 ) -> *mut Val;18}25}192620/// # Safety27/// # Safety26 jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx)33 jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx)27}34}3536/// # Safety37#[no_mangle]38pub unsafe extern "C" fn jrsonnet_apply_static_native_callback(39 vm: &EvaluationState,40 name: *const c_char,41 ctx: *mut c_void,42 raw_params: *const *const c_char,43) {44 jsonnet_native_callback(vm, name, _jrsonnet_static_native_callback, ctx, raw_params)45}284629#[no_mangle]47#[no_mangle]30pub extern "C" fn jrsonnet_set_trace_format(vm: &EvaluationState, format: u8) {48pub extern "C" fn jrsonnet_set_trace_format(vm: &EvaluationState, format: u8) {bindings/jsonnet/src/lib.rsdiffbeforeafterboth1pub mod import;1pub mod import;2pub mod interop;2pub mod interop;3pub mod native;3pub mod val_extract;4pub mod val_extract;4pub mod val_make;5pub mod val_make;5pub mod val_modify;6pub mod val_modify;92 Box::from_raw(v);93 Box::from_raw(v);93}94}9495#[no_mangle]96pub extern "C" fn jsonnet_native_callback() {97 todo!()98}9995100#[no_mangle]96#[no_mangle]101pub extern "C" fn jsonnet_max_trace(vm: &EvaluationState, v: c_uint) {97pub extern "C" fn jsonnet_max_trace(vm: &EvaluationState, v: c_uint) {bindings/jsonnet/src/native.rsdiffbeforeafterbothno changes
crates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth117 }117 }118 buf.push('}');118 buf.push('}');119 }119 }120 Val::Func(_) | Val::Intristic(_, _) => {120 Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _) => {121 throw!(RuntimeError("tried to manifest function".into()))121 throw!(RuntimeError("tried to manifest function".into()))122 }122 }123 Val::Lazy(_) => unreachable!(),123 Val::Lazy(_) => unreachable!(),crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth33 FunctionParameterNotBoundInCall(Rc<str>),33 FunctionParameterNotBoundInCall(Rc<str>),343435 UndefinedExternalVariable(Rc<str>),35 UndefinedExternalVariable(Rc<str>),36 UndefinedExternalFunction(Rc<str>),363737 FieldMustBeStringGot(ValType),38 FieldMustBeStringGot(ValType),3839crates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth5 },5 },6 context_creator, equals,6 context_creator, equals,7 error::Error::*,7 error::Error::*,8 future_wrapper, lazy_val, parse_args, primitive_equals, push, throw, with_state, Context,8 future_wrapper, lazy_val, parse_args, parse_function_call, primitive_equals, push, throw,9 ContextCreator, FuncDesc, LazyBinding, LazyVal, LocError, ObjMember, ObjValue, Result, Val,9 with_state, Context, ContextCreator, FuncDesc, LazyBinding, LazyVal, LocError, ObjMember,10 ValType,10 ObjValue, Result, Val, ValType,11};11};549 ], {549 ], {550 Ok(Val::Num(x.powf(n)))550 Ok(Val::Num(x.powf(n)))551 })?,551 })?,552 ("std", "extVar") => parse_args!(context, "std.extVar", args, 2, [552 ("std", "extVar") => parse_args!(context, "std.extVar", args, 1, [553 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];553 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];554 ], {554 ], {555 Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or_else(555 Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or_else(556 || UndefinedExternalVariable(x),556 || UndefinedExternalVariable(x),557 )?)557 )?)558 })?,558 })?,559 ("std", "native") => parse_args!(context, "std.native", args, 1, [560 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];561 ], {562 Ok(with_state(|s| s.settings().ext_natives.get(&x).cloned()).map(|v| Val::NativeExt(x.clone(), v)).ok_or_else(563 || UndefinedExternalFunction(x),564 )?)565 })?,559 ("std", "filter") => noinline!(parse_args!(context, "std.filter", args, 2, [566 ("std", "filter") => noinline!(parse_args!(context, "std.filter", args, 2, [560 0, func: [Val::Func]!!Val::Func, vec![ValType::Func];567 0, func: [Val::Func]!!Val::Func, vec![ValType::Func];561 1, arr: [Val::Arr]!!Val::Arr, vec![ValType::Arr];568 1, arr: [Val::Arr]!!Val::Arr, vec![ValType::Arr];780 })787 })781 },788 },782 )?,789 )?,790 Val::NativeExt(n, f) => push(791 loc,792 || format!("native <{}> call", n),793 || {794 let args = parse_function_call(context, None, &f.params, args, true)?;795 let mut out_args = Vec::with_capacity(f.params.len());796 for p in f.params.0.iter() {797 out_args.push(args.binding(p.0.clone())?.evaluate()?);798 }799 Ok(f.call(&out_args)?)800 },801 )?,783 Val::Func(f) => {802 Val::Func(f) => {784 let body = || f.evaluate(context, args, tailstrict);803 let body = || f.evaluate(context, args, tailstrict);785 if tailstrict {804 if tailstrict {crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth40 }40 }41 Value::Object(out)41 Value::Object(out)42 }42 }43 Val::Func(_) | Val::Intristic(_, _) => {43 Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _) => {44 throw!(RuntimeError("tried to manifest function".into()))44 throw!(RuntimeError("tried to manifest function".into()))45 }45 }46 })46 })crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth10mod import;10mod import;11mod integrations;11mod integrations;12mod map;12mod map;13pub mod native;13mod obj;14mod obj;14pub mod trace;15pub mod trace;15mod val;16mod val;21pub use function::parse_function_call;22pub use function::parse_function_call;22pub use import::*;23pub use import::*;23use jrsonnet_parser::*;24use jrsonnet_parser::*;25use native::NativeCallback;24pub use obj::*;26pub use obj::*;25use std::{27use std::{26 cell::{Ref, RefCell, RefMut},28 cell::{Ref, RefCell, RefMut},60 pub max_trace: usize,62 pub max_trace: usize,61 /// Used for std.extVar63 /// Used for std.extVar62 pub ext_vars: HashMap<Rc<str>, Val>,64 pub ext_vars: HashMap<Rc<str>, Val>,65 /// Used for ext.native66 pub ext_natives: HashMap<Rc<str>, Rc<NativeCallback>>,63 /// TLA vars67 /// TLA vars64 pub tla_vars: HashMap<Rc<str>, Val>,68 pub tla_vars: HashMap<Rc<str>, Val>,65 /// Global variables are inserted in default context69 /// Global variables are inserted in default context78 max_trace: 20,82 max_trace: 20,79 globals: Default::default(),83 globals: Default::default(),80 ext_vars: Default::default(),84 ext_vars: Default::default(),85 ext_natives: Default::default(),81 tla_vars: Default::default(),86 tla_vars: Default::default(),82 import_resolver: Box::new(DummyImportResolver),87 import_resolver: Box::new(DummyImportResolver),83 manifest_format: ManifestFormat::Json(4),88 manifest_format: ManifestFormat::Json(4),415 self.settings_mut().import_resolver = resolver;420 self.settings_mut().import_resolver = resolver;416 }421 }422423 pub fn add_native(&self, name: Rc<str>, cb: Rc<NativeCallback>) {424 self.settings_mut().ext_natives.insert(name, cb);425 }417426418 pub fn manifest_format(&self) -> ManifestFormat {427 pub fn manifest_format(&self) -> ManifestFormat {419 self.settings().manifest_format.clone()428 self.settings().manifest_format.clone()851 assert_eval!("{ x: 1, y: 2 } == { x: 1, y: 2 }")860 assert_eval!("{ x: 1, y: 2 } == { x: 1, y: 2 }")852 }861 }862863 #[test]864 fn native_ext() -> crate::error::Result<()> {865 use super::native::NativeCallback;866 let evaluator = EvaluationState::default();867868 evaluator.with_stdlib();869 evaluator.settings_mut().ext_natives.insert(870 "native_add".into(),871 Rc::new(NativeCallback::new(872 ParamsDesc(Rc::new(vec![873 Param("a".into(), None),874 Param("b".into(), None),875 ])),876 |args| match (&args[0], &args[1]) {877 (Val::Num(a), Val::Num(b)) => Ok(Val::Num(a + b)),878 (_, _) => todo!(),879 },880 )),881 );882 evaluator.evaluate_snippet_raw(883 Rc::new(PathBuf::from("test.jsonnet")),884 "std.assertEqual(std.native(\"native_add\")(1, 2), 3)".into(),885 )?;886 Ok(())887 }853}888}854889crates/jrsonnet-evaluator/src/native.rsdiffbeforeafterbothno changes
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth3 error::Error::*,3 error::Error::*,4 evaluate,4 evaluate,5 function::{parse_function_call, parse_function_call_map, place_args},5 function::{parse_function_call, parse_function_call_map, place_args},6 native::NativeCallback,6 throw, with_state, Context, ObjValue, Result,7 throw, with_state, Context, ObjValue, Result,7};8};8use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};9use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};152153153 // Library functions implemented in native154 // Library functions implemented in native154 Intristic(Rc<str>, Rc<str>),155 Intristic(Rc<str>, Rc<str>),156 NativeExt(Rc<str>, Rc<NativeCallback>),155}157}156macro_rules! matches_unwrap {158macro_rules! matches_unwrap {157 ($e: expr, $p: pat, $r: expr) => {159 ($e: expr, $p: pat, $r: expr) => {204 Val::Num(..) => ValType::Num,206 Val::Num(..) => ValType::Num,205 Val::Arr(..) => ValType::Arr,207 Val::Arr(..) => ValType::Arr,206 Val::Obj(..) => ValType::Obj,208 Val::Obj(..) => ValType::Obj,207 Val::Func(..) => ValType::Func,208 Val::Bool(_) => ValType::Bool,209 Val::Bool(_) => ValType::Bool,209 Val::Null => ValType::Null,210 Val::Null => ValType::Null,210 Val::Intristic(_, _) => ValType::Func,211 Val::Func(..) | Val::Intristic(_, _) | Val::NativeExt(_, _) => ValType::Func,211 Val::Lazy(_) => self.clone().unwrap_if_lazy()?.value_type()?,212 Val::Lazy(_) => self.clone().unwrap_if_lazy()?.value_type()?,212 })213 })213 }214 }343}344}344345345fn is_function_like(val: &Val) -> bool {346fn is_function_like(val: &Val) -> bool {346 matches!(val, Val::Func(_) | Val::Intristic(_, _))347 matches!(val, Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _))347}348}348349349/// Implements std.primitiveEquals builtin350/// Implements std.primitiveEquals builtin