java_spaghetti/refs/
local.rs1use std::fmt::{self, Debug, Display, Formatter};
2use std::ops::Deref;
3
4use jni_sys::*;
5
6use crate::{AssignableTo, Env, Global, Ref, ReferenceType, Return};
7
8#[repr(transparent)]
31pub struct Local<'env, T: ReferenceType> {
32 ref_: Ref<'env, T>,
33}
34
35impl<'env, T: ReferenceType> Local<'env, T> {
36 pub unsafe fn from_raw(env: Env<'env>, object: jobject) -> Self {
37 Self {
38 ref_: Ref::from_raw(env, object),
39 }
40 }
41
42 pub fn env(&self) -> Env<'env> {
43 self.ref_.env()
44 }
45
46 pub fn as_raw(&self) -> jobject {
47 self.ref_.as_raw()
48 }
49
50 pub fn into_raw(self) -> jobject {
51 let object = self.ref_.as_raw();
52 std::mem::forget(self); object
54 }
55
56 pub fn leak(self) -> Ref<'env, T> {
57 let result = self.ref_;
58 std::mem::forget(self); result
60 }
61
62 pub fn as_global(&self) -> Global<T> {
63 let env = self.env();
64 let jnienv = env.as_raw();
65 let object = unsafe { ((**jnienv).v1_2.NewGlobalRef)(jnienv, self.as_raw()) };
66 unsafe { Global::from_raw(env.vm(), object) }
67 }
68
69 pub fn as_ref(&self) -> Ref<'_, T> {
70 self.ref_
71 }
72
73 pub fn as_return(&self) -> Return<'env, T> {
74 let env: *mut *const JNINativeInterface_ = self.env().as_raw();
75 let object = unsafe { ((**env).v1_2.NewLocalRef)(env, self.as_raw()) };
76 unsafe { Return::from_raw(object) }
77 }
78
79 pub fn into_return(self) -> Return<'env, T> {
80 unsafe { Return::from_raw(self.into_raw()) }
81 }
82
83 pub fn cast<U: ReferenceType>(&self) -> Result<Local<'env, U>, crate::CastError> {
84 let env = self.env();
85 let jnienv = env.as_raw();
86 let class1 = unsafe { ((**jnienv).v1_2.GetObjectClass)(jnienv, self.as_raw()) };
87 let class2 = U::static_with_jni_type(|t| unsafe { env.require_class(t) });
88 if !unsafe { ((**jnienv).v1_2.IsAssignableFrom)(jnienv, class1, class2) } {
89 return Err(crate::CastError);
90 }
91 let object = unsafe { ((**jnienv).v1_2.NewLocalRef)(jnienv, self.as_raw()) };
92 Ok(unsafe { Local::from_raw(env, object) })
93 }
94
95 pub fn upcast<U: ReferenceType>(&self) -> Local<'env, U>
96 where
97 Self: AssignableTo<U>,
98 {
99 let env = self.env();
100 let jnienv = env.as_raw();
101 let object = unsafe { ((**jnienv).v1_2.NewLocalRef)(jnienv, self.as_raw()) };
102 unsafe { Local::from_raw(env, object) }
103 }
104}
105
106impl<'env, T: ReferenceType> From<Ref<'env, T>> for Local<'env, T> {
107 fn from(x: Ref<'env, T>) -> Self {
108 x.as_local()
109 }
110}
111
112impl<'env, T: ReferenceType> From<&Local<'env, T>> for Local<'env, T> {
113 fn from(x: &Local<'env, T>) -> Self {
114 x.clone()
115 }
116}
117
118impl<'env, T: ReferenceType> From<&Ref<'env, T>> for Local<'env, T> {
119 fn from(x: &Ref<'env, T>) -> Self {
120 x.as_local()
121 }
122}
123
124impl<'env, T: ReferenceType> Deref for Local<'env, T> {
125 type Target = T;
126 fn deref(&self) -> &Self::Target {
127 unsafe { &*(self as *const Self as *const Self::Target) }
128 }
129}
130
131impl<'env, T: ReferenceType> Clone for Local<'env, T> {
132 fn clone(&self) -> Self {
133 let env = self.env().as_raw();
134 let object = unsafe { ((**env).v1_2.NewLocalRef)(env, self.as_raw()) };
135 unsafe { Self::from_raw(self.env(), object) }
136 }
137}
138
139impl<'env, T: ReferenceType> Drop for Local<'env, T> {
140 fn drop(&mut self) {
141 let env = self.env().as_raw();
142 unsafe { ((**env).v1_2.DeleteLocalRef)(env, self.as_raw()) }
143 }
144}
145
146impl<'env, T: ReferenceType + Debug> Debug for Local<'env, T> {
147 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
148 (**self).fmt(f)
149 }
150}
151
152impl<'env, T: ReferenceType + Display> Display for Local<'env, T> {
153 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
154 (**self).fmt(f)
155 }
156}