Ext variables are not working while adding methods in global
redoC-A2k opened this issue · 2 comments
Jsonnet make
pub fn jsonnet_make() -> *mut VM {
let state = State::default();
state.settings_mut().import_resolver = tb!(FileImportResolver::default());
state.settings_mut().context_initializer = tb!(jrsonnet_stdlib::ContextInitializer::new(
state.clone(),
PathResolver::new_cwd_fallback(),
));
add_namespace(&state); // **here we are adding our global methods**
Box::into_raw(Box::new(VM {
state,
manifest_format: Box::new(JsonFormat::default()),
trace_format: Box::new(CompactFormat::default()),
tla_args: GcHashMap::default(),
}))
}
add_namespace function
fn add_namespace(state: &State) {
let mut bobj = ObjValueBuilder::new();
bobj.method("join", join::INST);
bobj.method("regexMatch", regex_match::INST);
state.add_global("arakoo".into(), Thunk::evaluated(Val::Obj(bobj.build())))
}
pub fn main() {
let vm = jsonnet_make();
// let filename = CString::new("filename").unwrap();
let filename = "filename";
let snippet = r#"
local username = std.extVar('name');
local Person(name='Alice') = {
name: name,
welcome: 'Hello ' + name + '!',
};
{
person1: Person(username),
person2: Person('Bob'),
}"#;
unsafe {
ext_string(
&mut *vm, // name.as_ptr() as *const c_char,
"name", // value.as_ptr() as *const c_char,
"afshan",
);
}
let result = unsafe { jsonnet_evaluate_snippet(&mut *vm, filename, snippet) };
println!("{}", result);
}
pub fn ext_string(vm: *mut VM, key: &str, value: &str) {
let vm = unsafe { &mut *vm };
let any_initializer = vm.state.context_initializer();
any_initializer
.as_any()
.downcast_ref::<jrsonnet_stdlib::ContextInitializer>()
.expect("only stdlib context initializer supported")
.add_ext_var(key.into(), Val::Str(value.into()));
}
Issue : We want to call regex_match and join method under arakoo namespace , it is working but when are trying to get value from external variable then we get panic as "only stdlib context initializer supported"
Expected : We should be able to call arakoo.regex_match and arakoo.join and also getting value from external variable should work .
VM struct is same as -> https://github.com/CertainLach/jrsonnet/blob/master/bindings/jsonnet/src/lib.rs#L75
This isn't obvious, but add_global and stdlib initializer are orthogonal,
any_initializer
.as_any()
.downcast_ref::<jrsonnet_stdlib::ContextInitializer>()
.expect("only stdlib context initializer supported")
Panics, because initializer here is not jrsonnet_stdlib::ContextInitializer
, but GlobalsCtx
defined here:
https://github.com/CertainLach/jrsonnet/blob/master/crates/jrsonnet-evaluator/src/lib.rs#L418-L454
In the future I want to drop those global initialization methods, but for now it is as it is, you need to set ext_strings before you add globals using add_global
, or you need to implement your own ContextInitializer
which will provide your own variables, as well as forward control to jrsonnet_stdlib
.
It is also possible to chain two initializers,
state.set_context_initializer((jrsonnet_stdlib::ContextInitializer, ArakooContextInitializer))
Where ArakooContextInitializer
will provide arakoo
global.
Example of ContextInitializer
initialization:
https://github.com/UniqueNetwork/chainql/blob/master/crates/chainql-core/src/lib.rs#L1657-L1688
And how to use it:
https://github.com/UniqueNetwork/chainql/blob/master/cmds/chainql/src/main.rs#L28-L32
Thanks a lot for helping , I have implemented ArakooContext and then managed jrsonnet_stdlib::Context from there