jnino/
lib.rs

1pub use derive_jface::JFace;
2use jni::{objects::JClass, JNIEnv};
3pub type Jr<T> = Result<T, Box<dyn std::error::Error>>;
4pub fn unit() {}
5pub fn hide<T>(_: T) {}
6
7pub trait Throwable<T> {
8  fn throw<L: FnOnce() -> T>(self, jenv: JNIEnv, or_else: L) -> T;
9}
10impl<T> Throwable<T> for Jr<T> {
11  fn throw<L: FnOnce() -> T>(self, jenv: JNIEnv, or_else: L) -> T {
12    match self {
13      Ok(it) => it,
14      Err(e) => {
15        let _ = jenv.throw(e.to_string()).map_err(|e| log::warn!("can't throw: {}", e));
16        or_else()
17      }
18    }
19  }
20}
21
22pub trait JFace: Sized {
23  fn mut_raw<'a>(jenv: &JNIEnv<'a>, jclass: JClass<'a>) -> Jr<Option<&'a mut Self>> {
24    let r = jenv.get_field(jclass, "ptr", "J")?.j()? as isize;
25    unsafe {
26      let r: usize = std::mem::transmute(r);
27      let r: *mut Self = r as _;
28      if let Some(r) = r.as_mut() {
29        Ok(Some(r))
30      } else {
31        Ok(None)
32      }
33    }
34  }
35  fn box_raw<'a>(jenv: &JNIEnv<'a>, jclass: JClass<'a>) -> Jr<Option<Box<Self>>> {
36    Self::mut_raw(jenv, jclass).and_then(|it| {
37      it.map(|it| unsafe {
38        jenv.set_field(jclass, "ptr", "J", 0.into()).map_err(Box::new)?;
39        Ok(Box::from_raw(it))
40      })
41      .transpose()
42    })
43  }
44  fn jni(self) -> *mut Self {
45    Box::into_raw(Box::new(self))
46  }
47}
48
49pub trait JRConv<T> {
50  fn jni(self) -> Jr<*mut T>;
51}
52impl<T: JFace, E: Into<Box<dyn std::error::Error>>> JRConv<T> for Result<T, E> {
53  fn jni(self) -> Jr<*mut T> {
54    self.map_err(Into::into).map(JFace::jni)
55  }
56}