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