Loading repository data…
Loading repository data…
konstin / repository
A framework for generating bindings from Rust to python, helix and javascript
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
A framework for generating bindings from Rust to dynamic languages. Currently supports python (via pyo3), ruby (via helix) and javascript (via wasm-bindgen).
Note: This is in alpha stage. You can't do much more than structs, methods and functions with the basic types yet. (And in ruby not even freestanding functions yet)
The boilerplate:
#![feature(specialization)]
#[macro_use]
extern crate capybara;
use capybara::prelude::*;
Annotate every struct, impl-block and function you want to export with #[capybara]:
#[capybara]
fn double(x: usize) -> usize {
x * 2
}
#[capybara]
pub struct ExportedClass {}
#[capybara]
impl ExportedClass {
fn print_and_add(x: i32, y: i32) -> i32 {
println!("Printing from rust: {}", x + y);
x + y
}
}
We also need to generate an extrypoint for module/package/gem on the target site. This is done by calling capybara_init!
with the name of module/package, the names of the structs to generate classes from and the names of the functions to be exported.
capybara_init! {capybara_test, [ExportedClass], [double]}
Add the following to your Cargo.toml:
[lib]
name = "<Name of the module you used in capybara_init!>"
crate-type = ["cdylib"]
If you only target a single language, you can use the features option. Available are "python", "ruby" and "wasm".
These options are mutually exclusive.
[dependencies]
capybara = { version = "0.1.0", features = ["python"] }
To select the language for each build, omit the features part and pass the target language with --features to
cargo build, e.g. with cargo build --features capybara/ruby.
Python is supported through a library called pyo3. You can use pyo3-pack or setuptools-rust for building and packaging.
To module without external tools, copy the lib<module name>.so built by cargo from the target folder and
rename it to <module name>.so in the working directory. You can then import <module name>. Hint: Use <module name>.__dict__ to see what's in there.
Follow helix' great getting started, but replace the lib.rs and cargo
dependencies wth the ones from this repo. You also need to patch project.rb in the helix_runtime gem with this project.rb until tildeio/helix#148 is finally merged.
The #[capybara] is essentially #[wasm_bindgen] with less featues.
Read wasm-bindgen's awesome getting started on how to generate bindings.
Note that extern blocks can not use annotations on functions (which are required for e.g. console.log) and that
println!() doesn't print for that target, so you effectively must check the return value of a call into rust in the
javascript to see whether everything is set up correctly.
The main goal is making capybara as intuitive as possible, meaning that you can develop crossing ffi boundaries the same way that you normally develop.
__add__ in python and def + in ruby)crate-type = ["cdylib"], items must be pub, etc.rails generate helix:crate text_transformCapybara needs to rewrite your constructors to make them work with the underlying libraries. Therefore a constructor must be called new, annotated with #[capybara(constructor)], there must be no return statements inside the function and the instance must be built in the last expression of the function. Example:
#[capybara]
pub struct ExportedClass {
x: usize,
y: usize,
}
#[capybara]
impl ExportedClass {
#[capybara(constructor)]
fn new(x: usize) -> ExportedClass {
println!("Building an instance");
ExportedClass {
x,
y: x+3,
}
}
}
The most convenient solution is cargo expand.
Without installing cargo expand, you can use
cargo rustc --profile=check -- -Zunstable-options --pretty=expanded
With rustfmt installed, you can get easily get a pretty-printed version
cargo rustc --profile=check -- -Zunstable-options --pretty=expanded > expanded.rs; rustfmt expanded.rs
For helix, tracing macro expansion can be relevant
cargo rustc --profile=check -- -Z unstable-options --pretty=expanded -Z trace-macros > expanded.rs; rustfmt expanded.rs
There is also a "debug-macros" features which dumps the token stream with the hygiene information.
There is an integration testing system checking compilation and different kinds of method signatures for all targets. Use test.sh to run all tests.
There is also expand.sh in compare-codegen, which allows easily comparing the code generated by capybara with the one generated by invocing the underlying libraries (helix, pyo3 and wasm-bindgen) directly. It will both create files to compare in the tool of your choice and a simple diff output.
Contributions are welcome!
Please run cargo fmt and - if you are on linux or mac - ./test.sh before submitting pull requests.
This project is licensed under either of
at your option.