CertainLach/jrsonnet

Unable to read arguments on native functions (Using C bindings)

julienduchesne opened this issue · 3 comments

Hello, I'm not sure if this is a bug but I'm a bit stumped because I don't know enough about Rust and C

I'm working on integrating jrsonnet into Tanka as an alternative jsonnet implementation to go-jsonnet. I've got everything working except native functions

I used this code as a base to link Go with the C bindings and jrsonnet:
https://github.com/strickyak/jsonnet_cgo/blob/master/jsonnet.go

Native functions bind correctly and are called but I've got two problems:

  • I'm not able to read the arguments that are passed from jsonnet., the user passes std.native('myfunc')('arg1', 'arg2') but the args structure I get is nil
  • If I do get the above working, I've got extract functions for string, number, bool and null but users can also use objects and arrays as parameters. Any way to get those from Rust -> golang?

Do you think there's a better approach that could be used to integrate jrsonnet to golang?

I'm not able to read the arguments that are passed from jsonnet. the user passes std.native('myfunc')('arg1', 'arg2') but the args structure I get is nil

There was a bug in C bindings (They are not used much); it is fixed here: 2e3471b, and I have added an example here: 96690c7

If I do get the above working, I've got extract functions for string, number, bool and null, but users can also use objects and arrays as parameters. Any way to get those from Rust -> golang?

C bindings are C bindings; they are only implementing what is defined in libjsonnet.h (https://github.com/google/jsonnet/blob/master/include/libjsonnet.h), and there are no extractors for objects/arrays. I think you are supposed to use JSON serialization/serialization for complex objects when you use C bindings.

They (Object/array extractors) could be implemented, but I would recommend writing your bindings against jrsonnet itself instead of using C bindings.
This way you will have full control of jrsonnet VM, which has a very different API compared to C bindings. It would also be easier to implement some necessary conversions on the Rust side instead of being limited by libjsonnet.h.

There is an example of Python bindings for jrsonnet: https://github.com/messense/rjsonnet-py/blob/main/src/lib.rs

As for golang... I don't know the story about golang Rust FFI support, but as I can see, there is not much in this field.
I don't see anything like PyO3, but I think https://github.com/mozilla/cbindgen will make this job easier.

Awesome, cbindgen looks good! Python <-> Rust interop looks much more fleshed out than Golang <-> Rust indeed. I'll try cbindgen out and report back! Thanks for the quick response

Great project btw, really eager to speed up Tanka 10x 😄. Projects that don't require native functions work great already!

Last time I was needed to do Golang <-> Rust interop (I was implementing helm templating support in my own tanka-like templating tool), I spent some hours trying to link golang assembly to rust, gave up, and proceeded to call helm as external process instead: https://github.com/CertainLach/hayasaka/blob/build/src/helm/template.rs#L53 (haya is not open-source, this repo is outdated, and doesn't have anything useful)

But don't let my experience demotivate you, as linking Rust to Golang should be much smoother than Golang to Rust :D

Regards