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}