Skip to main content

jvm/
class_instance.rs

1use alloc::boxed::Box;
2use core::{
3    fmt::{self, Debug, Formatter},
4    marker::PhantomData,
5    ops::{Deref, DerefMut},
6};
7
8use dyn_clone::{DynClone, clone_trait_object};
9use dyn_hash::{DynHash, hash_trait_object};
10
11use crate::{ArrayClassInstance, ClassDefinition, Field, Result, as_any::AsAny, value::JavaValue};
12
13#[async_trait::async_trait]
14pub trait ClassInstance: Sync + Send + AsAny + Debug + DynHash + DynClone + 'static {
15    fn destroy(self: Box<Self>);
16    fn identity(&self) -> usize;
17    fn shallow_clone(&self) -> Result<Box<dyn ClassInstance>>;
18    fn class_definition(&self) -> Box<dyn ClassDefinition>;
19    fn equals(&self, other: &dyn ClassInstance) -> Result<bool>;
20    fn get_field(&self, field: &dyn Field) -> Result<JavaValue>;
21    fn put_field(&mut self, field: &dyn Field, value: JavaValue) -> Result<()>;
22    fn as_array_instance(&self) -> Option<&dyn ArrayClassInstance> {
23        None
24    }
25    fn as_array_instance_mut(&mut self) -> Option<&mut dyn ArrayClassInstance> {
26        None
27    }
28}
29
30pub trait AsClassInstance {
31    fn as_class_instance(&self) -> &dyn ClassInstance;
32}
33
34impl<T: ClassInstance> AsClassInstance for T {
35    fn as_class_instance(&self) -> &dyn ClassInstance {
36        self
37    }
38}
39
40impl AsClassInstance for dyn ClassInstance {
41    fn as_class_instance(&self) -> &dyn ClassInstance {
42        self
43    }
44}
45
46impl AsClassInstance for Box<dyn ClassInstance> {
47    fn as_class_instance(&self) -> &dyn ClassInstance {
48        self.as_ref()
49    }
50}
51
52clone_trait_object!(ClassInstance);
53hash_trait_object!(ClassInstance);
54
55impl Eq for dyn ClassInstance {}
56impl PartialEq for dyn ClassInstance {
57    fn eq(&self, other: &Self) -> bool {
58        self.equals(other).unwrap()
59    }
60}
61
62// array wrapper for ClassInstanceRef
63pub struct Array<T>(PhantomData<T>);
64
65// typesafe wrapper for ClassInstance
66pub struct ClassInstanceRef<T> {
67    pub instance: Option<Box<dyn ClassInstance>>,
68    _phantom: PhantomData<T>,
69}
70
71impl<T> ClassInstanceRef<T> {
72    pub fn new(instance: Option<Box<dyn ClassInstance>>) -> Self {
73        Self {
74            instance,
75            _phantom: PhantomData,
76        }
77    }
78}
79
80impl<T> Clone for ClassInstanceRef<T> {
81    fn clone(&self) -> Self {
82        Self {
83            instance: self.instance.clone(),
84            _phantom: PhantomData,
85        }
86    }
87}
88
89impl<T> ClassInstanceRef<T> {
90    pub fn is_null(&self) -> bool {
91        self.instance.is_none()
92    }
93}
94
95impl<T> Debug for ClassInstanceRef<T> {
96    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97        if let Some(x) = &self.instance {
98            write!(f, "{x:?}")
99        } else {
100            write!(f, "null")
101        }
102    }
103}
104
105impl<T> Deref for ClassInstanceRef<T> {
106    type Target = Box<dyn ClassInstance>;
107    fn deref(&self) -> &Self::Target {
108        self.instance.as_ref().unwrap()
109    }
110}
111
112impl<T> DerefMut for ClassInstanceRef<T> {
113    fn deref_mut(&mut self) -> &mut Self::Target {
114        self.instance.as_mut().unwrap()
115    }
116}
117
118impl<T> AsClassInstance for ClassInstanceRef<T> {
119    fn as_class_instance(&self) -> &dyn ClassInstance {
120        self.instance.as_deref().unwrap()
121    }
122}
123
124impl<T> From<ClassInstanceRef<T>> for JavaValue {
125    fn from(value: ClassInstanceRef<T>) -> Self {
126        value.instance.into()
127    }
128}
129
130impl<T> From<Box<dyn ClassInstance>> for ClassInstanceRef<T> {
131    fn from(value: Box<dyn ClassInstance>) -> Self {
132        Self {
133            instance: Some(value),
134            _phantom: PhantomData,
135        }
136    }
137}
138
139impl<T> From<Option<Box<dyn ClassInstance>>> for ClassInstanceRef<T> {
140    fn from(value: Option<Box<dyn ClassInstance>>) -> Self {
141        Self {
142            instance: value,
143            _phantom: PhantomData,
144        }
145    }
146}
147
148impl<T> From<JavaValue> for ClassInstanceRef<T> {
149    fn from(val: JavaValue) -> Self {
150        ClassInstanceRef {
151            instance: val.into(),
152            _phantom: PhantomData,
153        }
154    }
155}
156
157impl<T> From<ClassInstanceRef<T>> for Box<dyn ClassInstance> {
158    fn from(value: ClassInstanceRef<T>) -> Self {
159        value.instance.unwrap()
160    }
161}
162
163impl<T> From<ClassInstanceRef<T>> for Option<Box<dyn ClassInstance>> {
164    fn from(value: ClassInstanceRef<T>) -> Self {
165        value.instance
166    }
167}