I'm creating a scientific simulation library in Rust that I want to call from various languages. For now, let's assume I just want to use the Rust library from Python and JS (via WebAssembly).
I'm keen to use crates like wasm-bindgen and pyo3 to generate the language bindings automatically using various macros.
Since these bindgen libraries are not necessarily compatible with each other, I understand I will probably have to write some duplicate code to expose my library's API to different languages. My question is: are there any best practices for doing this sort of thing? Ideally, I'd like to expose the same API to each language and minimize the amount of redundant code.
Sounds to me like you need to create your simulation library as a stand alone thing. A crate of its own I guess. Then create the JS and Python wrappers as separate items.
Yes, I think you're right. I'll put core functionality in one crate, as part of a Rust workspace, and create a separate crate for each external language.
A bit of searching brought up UniFFI and Diplomat, which can auto-generate bindings for multiple languages. These might be worth looking into for anyone facing the same problem.
Also have a look at the API design of 0mq vs the API of its Python bindings. While the Python bindings are of course more pythonic than the C api, the similarity between them makes it easy to use one API if you've used the library in the other language, and in that respect 0mq and its Python bindings are a pretty nice example.
In my experience, the best way to approach this is to write the bindings for each crate manually and keep them in the same repo as your crate to make sure the packages stay in sync.
Automated tools that can generate bindings for each language are convenient for the developer, but have the downside that the generated code feels clunky and unidiomatic for the user. It's hard to automatically generate code that feels idiomatic because different programming languages want to write code in different ways. Maybe developments in AI will change that, but for now nothing beats a human touch.
Absolutely, it's good to get confirmation from several people that automation isn't the silver bullet. I suspected it all along but was afraid I was missing something.