• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::{
2     descriptors::Desc,
3     errors::*,
4     objects::{AutoLocal, GlobalRef, JClass, JObject},
5     strings::JNIString,
6     JNIEnv,
7 };
8 
9 unsafe impl<'local, T> Desc<'local, JClass<'local>> for T
10 where
11     T: Into<JNIString>,
12 {
13     type Output = AutoLocal<'local, JClass<'local>>;
14 
lookup(self, env: &mut JNIEnv<'local>) -> Result<Self::Output>15     fn lookup(self, env: &mut JNIEnv<'local>) -> Result<Self::Output> {
16         Ok(AutoLocal::new(env.find_class(self)?, env))
17     }
18 }
19 
20 // Note: We don't implement `Desc<JClass>` for `&JObject` as a transmute like for `GlobalRef`
21 //
22 // Considering that the APIs that return a class return a `JClass` it shouldn't
23 // usually be necessary unless the `JClass` got type erased (like with GlobalRef)
24 //
25 // Implementing `Desc<JClass>` for `&JObject` as a simple cast would also make
26 // it a lot easier to mistakenly pass an object instance in places where a class
27 // is required.
28 
29 /// This conversion assumes that the `GlobalRef` is a pointer to a class object.
30 
31 // TODO: Generify `GlobalRef` and get rid of this `impl`. The transmute is
32 // sound-ish at the moment (`JClass` is currently `repr(transparent)`
33 // around `JObject`), but that may change in the future. Moreover, this
34 // doesn't check if the global reference actually refers to a
35 // `java.lang.Class` object.
36 unsafe impl<'local, 'obj_ref> Desc<'local, JClass<'static>> for &'obj_ref GlobalRef {
37     type Output = &'obj_ref JClass<'static>;
38 
lookup(self, _: &mut JNIEnv<'local>) -> Result<Self::Output>39     fn lookup(self, _: &mut JNIEnv<'local>) -> Result<Self::Output> {
40         let obj: &JObject<'static> = self.as_ref();
41         Ok(unsafe { std::mem::transmute(obj) })
42     }
43 }
44