toad-jni

Crates.iotoad-jni
lib.rstoad-jni
version1.0.0-beta.3
sourcesrc
created_at2023-04-04 23:10:34.438969
updated_at2023-07-13 15:42:51.329169
descriptionJNI abstractions and bindings used by the toad ecosystem
homepagehttps://github.com/clov-coffee/toad/toad
repositoryhttps://github.com/clov-coffee/toad/toad
max_upload_size
id830538
size151,334
Orion Kindel (cakekindel)

documentation

README

crates.io docs.rs Maintenance

toad-jni

High-level wrapper of [jni], making Java & Rust FFI easy & fun

Globals

toad_jni::global offers the option to use a global JVM handle (toad_jni::global::jvm() set with toad_jni::global::init()).

Using the JVM global is completely optional, unless you plan to use Rust trait impls such as [IntoIterator] on toad_jni::java::util::ArrayList.

Types

All java type signatures can be represented by rust types that implement the toad_jni::java::Type trait, which is automatically implemented for all toad_jni::java::Classes.

Classes

Classes are represented in toad_jni by implementing 2 traits:

Fields and Methods

There are several high-level lens-style structs for interacting with fields, methods and constructors:

All of these types use toad_jni::java::Type to transform nice Rust types into the corresponding JVM type signatures.

For example, the StaticMethod representation of java.lang.String.format(String, ..Object) would be:

use toad_jni::java::lang::Object;
use toad_jni::java::StaticMethod;

static STRING_FORMAT: StaticMethod<String, fn(String, Vec<Object>) -> String> =
  StaticMethod::new("format");

It is recommended that these structs are stored in local static variables so that they can cache the internal JNI IDs of the class and methods, but this is not required.

Example

Consider the following java class:

package com.foo.bar;

public class Foo {
  public final static long NUMBER = 123;
  public String bingus = "bingus";

  public Foo() { }

  public static String bar() {
    return "bar";
  }

  public void setBingus(String newBingus) {
    this.bingus = newBingus;
  }
}

A Rust API to this class would look like:

use toad_jni::java;

pub struct Foo(java::lang::Object);

java::object_newtype!(Foo);

impl java::Class for Foo {
  const PATH: &'static str = "com/foo/bar/Foo";
}

impl Foo {
  pub fn new(e: &mut java::Env) -> Self {
    static CTOR: java::Constructor<Foo, fn()> = java::Constructor::new();
    CTOR.invoke(e)
  }

  pub fn number(e: &mut java::Env) -> i64 {
    static NUMBER: java::StaticField<Foo, i64> = java::StaticField::new("NUMBER");
    NUMBER.get(e)
  }

  pub fn bar(e: &mut java::Env) -> String {
    static BAR: java::StaticMethod<Foo, fn() -> String> = java::StaticMethod::new("bar");
    BAR.invoke(e)
  }

  pub fn bingus(&self, e: &mut java::Env) -> String {
    static BINGUS: java::Field<Foo, String> = java::Field::new("bingus");
    BINGUS.get(e, self)
  }

  pub fn set_bingus(&self, e: &mut java::Env, s: String) {
    static SET_BINGUS: java::Method<Foo, fn(String)> = java::Method::new("setBingus");
    SET_BINGUS.invoke(e, self, s)
  }
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 0

cargo fmt