java_spaghetti/refs/
ref_.rs
1use std::fmt::{self, Debug, Display, Formatter};
2use std::marker::PhantomData;
3use std::ops::Deref;
4
5use jni_sys::jobject;
6
7use crate::{AssignableTo, Env, Global, Local, ObjectAndEnv, ReferenceType};
8
9#[repr(transparent)]
17pub struct Ref<'env, T: ReferenceType> {
18 oae: ObjectAndEnv,
19 _env: PhantomData<Env<'env>>,
20 _class: PhantomData<&'env T>,
21}
22
23impl<'env, T: ReferenceType> Copy for Ref<'env, T> {}
24impl<'env, T: ReferenceType> Clone for Ref<'env, T> {
25 fn clone(&self) -> Self {
26 Self {
27 oae: self.oae,
28 _env: PhantomData,
29 _class: PhantomData,
30 }
31 }
32}
33
34impl<'env, T: ReferenceType> Ref<'env, T> {
35 pub unsafe fn from_raw(env: Env<'env>, object: jobject) -> Self {
36 Self {
37 oae: ObjectAndEnv {
38 object,
39 env: env.as_raw(),
40 },
41 _env: PhantomData,
42 _class: PhantomData,
43 }
44 }
45
46 pub fn env(&self) -> Env<'env> {
47 unsafe { Env::from_raw(self.oae.env) }
48 }
49
50 pub fn as_raw(&self) -> jobject {
51 self.oae.object
52 }
53
54 pub fn as_global(&self) -> Global<T> {
55 let env = self.env();
56 let jnienv = env.as_raw();
57 let object = unsafe { ((**jnienv).v1_2.NewGlobalRef)(jnienv, self.as_raw()) };
58 unsafe { Global::from_raw(env.vm(), object) }
59 }
60
61 pub fn as_local(&self) -> Local<'env, T> {
62 let env = self.env();
63 let jnienv = env.as_raw();
64 let object = unsafe { ((**jnienv).v1_2.NewLocalRef)(jnienv, self.as_raw()) };
65 unsafe { Local::from_raw(self.env(), object) }
66 }
67
68 pub fn cast<U: ReferenceType>(&self) -> Result<Ref<'env, U>, crate::CastError> {
69 let env = self.env();
70 let jnienv = env.as_raw();
71 let class1 = unsafe { ((**jnienv).v1_2.GetObjectClass)(jnienv, self.as_raw()) };
72 let class2 = U::static_with_jni_type(|t| unsafe { env.require_class(t) });
73 if !unsafe { ((**jnienv).v1_2.IsAssignableFrom)(jnienv, class1, class2) } {
74 return Err(crate::CastError);
75 }
76 Ok(unsafe { Ref::from_raw(env, self.as_raw()) })
77 }
78
79 pub fn upcast<U: ReferenceType>(&self) -> Ref<'env, U>
80 where
81 Self: AssignableTo<U>,
82 {
83 let env = self.env();
84 unsafe { Ref::from_raw(env, self.as_raw()) }
85 }
86}
87
88impl<'env, T: ReferenceType> Deref for Ref<'env, T> {
89 type Target = T;
90 fn deref(&self) -> &Self::Target {
91 unsafe { &*(&self.oae as *const ObjectAndEnv as *const Self::Target) }
92 }
93}
94
95impl<'env, T: ReferenceType + Debug> Debug for Ref<'env, T> {
96 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97 (**self).fmt(f)
98 }
99}
100
101impl<'env, T: ReferenceType + Display> Display for Ref<'env, T> {
102 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
103 (**self).fmt(f)
104 }
105}