1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
//! This library provides a procedural macro to make easier to write JNI-compatible code in Rust. //! //! It can perform automatic conversion of Rust-y input and output types (see the [limitations](#limitations)). //! //! ```toml //! [dependencies] //! robusta_jni = "0.0.3" //! ``` //! //! ## Usage //! All that's needed is a couple of attributes in the right places. //! //! First, a `#[bridge]` attribute on a module will enable it to be processed by `robusta`. //! //! Then, we will need a struct for every class with a native method that will be implemented in Rust, //! and each of these structs will have to be annotated with a `#[package]` attribute //! with the name of the Java package the corresponding class belongs to. //! //! After that, the functions implemented can be written as ordinary Rust functions, and the macro will //! take care of converting to and from Java types. By default if a conversion fails a Java exception is thrown. //! //! **NOTE: This library currently supports static methods only.** //! //! ## Example //! ### Rust side //! ```rust //! use robusta_jni::bridge; //! //! #[bridge] //! mod jni { //! #[package(com.example.robusta)] //! struct HelloWorld; //! //! impl HelloWorld { //! fn special(mut input1: Vec<i32>, input2: i32) -> Vec<String> { //! input1.push(input2); //! input1.iter().map(ToString::to_string).collect() //! } //! } //! } //! ``` //! //! ### Java side //! ```java //! package com.example.robusta; //! //! import java.util.*; //! //! class HelloWorld { //! private static native ArrayList<String> special(ArrayList<Integer> input1, int input2); //! //! static { //! System.loadLibrary("robusta_example"); //! } //! //! public static void main(String[] args) { //! ArrayList<String> output = HelloWorld.special(new ArrayList<Integer>(List.of(1, 2, 3)), 4); //! System.out.println(output) //! } //! } //! ``` //! //! ## Type conversion details and extension to custom types //! There are four traits that control how Rust types are converted to/from Java types: //! `(Try)FromJavaValue` and `(Try)IntoJavaValue`. //! //! These traits are used for input and output types respectively, and implementing them //! is necessary to allow the library to perform automatic type conversion. By default, the `Try` variants are used, //! all of which throw a Java exception upon failure. This behaviour can be changed via the `call_type` attribute //! (see the `convert` module documentation for more details). //! //! These traits make use of type provided by the [`jni`](https://crates.io/crates/jni) crate, //! however to provide maximum compatibility with `robusta`, we suggest using the re-exported version under `robusta_jni::jni`. //! //! ### Conversion table //! //! | **Rust** | **Java** | //! |------------------------------------------------------------------------------------|-------------------------------------| //! | [`i32`] | `int` | //! | [`bool`] | `boolean` | //! | [`char`] | `char` | //! | [`i8`] | `byte` | //! | [`f32`] | `float` | //! | [`f64`] | `double` | //! | [`i64`] | `long` | //! | [`i16`] | `short` | //! | [`Vec<T>`](std::vec::Vec)† | `ArrayList<T>` | //! | [`JObject<'env>`](jni::objects::JObject)‡ | *(any Java object as input type)* | //! | [`jobject`](jni::sys::jobject) | *(any Java object as output)* | //! //! † Type parameter `T` must implement proper conversion types //! //! ‡ The special `'env` lifetime **must** be used //! //! ## Limitations //! Only static methods are supported. //! //! Currently there are some limitations in the conversion mechanism: //! * Boxed types are supported only through the opaque `JObject`/`jobject` types //! * Automatic type conversion is limited to the table outlined above, though easily extendable if needed. //! pub use robusta_codegen::bridge; pub mod convert; #[cfg(not(feature = "no_jni"))] pub use jni;