Skip to main content

toad_jni/java/
result.rs

1use java::lang::Throwable;
2use jni::objects::{JObject, JThrowable};
3use jni::sys::jobject;
4
5use crate::java::{self, Object};
6
7/// Handle a `Result<impl java::Object, Throwable>` in a native
8/// method implementation.
9///
10/// if `Err` throw the [`Throwable`] contained in the result.
11///
12/// if `Ok` invoke [`java::Object::yield_to_java`].
13pub trait ResultYieldToJavaOrThrow {
14  #[allow(missing_docs)]
15  fn yield_to_java_or_throw(self, e: &mut java::Env) -> jobject;
16}
17
18impl<T> ResultYieldToJavaOrThrow for Result<T, Throwable> where T: java::Object
19{
20  fn yield_to_java_or_throw(self, e: &mut java::Env) -> jobject {
21    self.map(|ok| ok.yield_to_java(e))
22        .map_err(|err| {
23          let err = JThrowable::from(err.downcast(e).to_local(e));
24          e.throw(err).unwrap()
25        })
26        .unwrap_or(*JObject::null())
27  }
28}
29
30/// [`toad_jni::errors::Result`] interop helpers
31pub trait ResultExt<T> {
32  /// If a java exception occurred, toString it and panic
33  fn unwrap_java(self, e: &mut java::Env) -> T;
34
35  /// If a java exception occurred, convert to [`java::lang::Throwable`]
36  fn to_throwable(self, e: &mut java::Env) -> Result<T, Throwable>;
37}
38
39impl<T> ResultExt<T> for jni::errors::Result<T> {
40  fn unwrap_java(self, e: &mut java::Env) -> T {
41    use jni::errors::Error::*;
42
43    match self {
44      | Ok(t) => t,
45      | Err(JavaException) => {
46        let ex = e.exception_occurred().unwrap();
47        let exo = java::lang::Object::from_local(e, ex);
48        e.exception_clear().unwrap();
49        panic!("{:?}", exo.upcast_to::<java::lang::Throwable>(e));
50      },
51      | o => o.unwrap(),
52    }
53  }
54
55  fn to_throwable(self, e: &mut java::Env) -> Result<T, java::lang::Throwable> {
56    use jni::errors::Error::*;
57
58    match self {
59      | Err(JavaException) => {
60        let ex = e.exception_occurred().unwrap();
61        e.exception_clear().unwrap();
62        let exo = java::lang::Object::from_local(e, ex);
63        Err(java::lang::Throwable::upcast(e, exo))
64      },
65      | o => Ok(o.unwrap()),
66    }
67  }
68}