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
62pub struct Array<T>(PhantomData<T>);
64
65pub 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}