1use std::rc::Rc;
2
3use crate::model::*;
4
5#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7pub(crate) enum ClassType {
8 Normal,
10 Iterator,
12 Collection,
14}
15
16#[derive(Debug)]
18pub struct ClassDeclaration {
19 pub(crate) name: Name,
20 pub(crate) class_type: ClassType,
21 pub(crate) settings: Rc<LibrarySettings>,
22}
23
24#[derive(Debug, Clone)]
25pub(crate) struct IteratorClassDeclaration {
26 pub(crate) inner: ClassDeclarationHandle,
27}
28
29impl IteratorClassDeclaration {
30 pub(crate) fn new(inner: ClassDeclarationHandle) -> Self {
31 Self { inner }
32 }
33}
34
35#[derive(Debug, Clone)]
36pub(crate) struct CollectionClassDeclaration {
37 pub(crate) inner: ClassDeclarationHandle,
38}
39
40impl CollectionClassDeclaration {
41 pub(crate) fn new(inner: ClassDeclarationHandle) -> Self {
42 Self { inner }
43 }
44}
45
46impl ClassDeclaration {
47 pub(crate) fn new(name: Name, class_type: ClassType, settings: Rc<LibrarySettings>) -> Self {
48 Self {
49 name,
50 class_type,
51 settings,
52 }
53 }
54}
55
56pub type ClassDeclarationHandle = Handle<ClassDeclaration>;
57
58#[derive(Debug, Clone)]
60pub struct Method<T>
61where
62 T: DocReference,
63{
64 pub(crate) name: Name,
65 pub(crate) associated_class: Handle<ClassDeclaration>,
66 pub(crate) native_function: Handle<Function<T>>,
67}
68
69impl Method<Unvalidated> {
70 pub(crate) fn new(
71 name: Name,
72 associated_class: Handle<ClassDeclaration>,
73 function: Handle<Function<Unvalidated>>,
74 ) -> Self {
75 Self {
76 name,
77 associated_class,
78 native_function: function,
79 }
80 }
81
82 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<Method<Validated>> {
83 Ok(Method {
84 name: self.name.clone(),
85 associated_class: self.associated_class.clone(),
86 native_function: self.native_function.validate(lib)?,
87 })
88 }
89}
90
91pub type MethodHandle = Method<Unvalidated>;
92
93#[derive(Debug)]
97pub struct StaticMethod<T>
98where
99 T: DocReference,
100{
101 pub(crate) name: Name,
102 pub(crate) native_function: Handle<Function<T>>,
103}
104
105impl StaticMethod<Unvalidated> {
106 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<StaticMethod<Validated>> {
107 Ok(StaticMethod {
108 name: self.name.clone(),
109 native_function: self.native_function.validate(lib)?,
110 })
111 }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq)]
115pub(crate) enum DestructionMode {
116 Automatic,
118 Custom(Name),
124 Dispose,
130}
131
132impl DestructionMode {
133 pub(crate) fn is_manual_destruction(&self) -> bool {
134 match self {
135 Self::Automatic => false,
136 Self::Custom(_) => true,
137 Self::Dispose => true,
138 }
139 }
140}
141
142#[derive(Debug)]
144pub struct Class<T>
145where
146 T: DocReference,
147{
148 pub(crate) declaration: ClassDeclarationHandle,
149 pub(crate) constructor: Option<ClassConstructor<T>>,
150 pub(crate) destructor: Option<ClassDestructor<T>>,
151 pub(crate) methods: Vec<Method<T>>,
152 pub(crate) static_methods: Vec<StaticMethod<T>>,
153 pub(crate) future_methods: Vec<FutureMethod<T>>,
154 pub(crate) doc: Doc<T>,
155 pub(crate) destruction_mode: DestructionMode,
156 pub(crate) settings: Rc<LibrarySettings>,
157}
158
159impl Class<Unvalidated> {
160 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<Handle<Class<Validated>>> {
161 let constructor = match &self.constructor {
162 None => None,
163 Some(x) => Some(x.validate(lib)?),
164 };
165 let destructor = match &self.destructor {
166 None => None,
167 Some(x) => Some(x.validate(lib)?),
168 };
169 let methods: BindResult<Vec<Method<Validated>>> =
170 self.methods.iter().map(|x| x.validate(lib)).collect();
171 let static_methods: BindResult<Vec<StaticMethod<Validated>>> = self
172 .static_methods
173 .iter()
174 .map(|x| x.validate(lib))
175 .collect();
176 let async_methods: BindResult<Vec<FutureMethod<Validated>>> = self
177 .future_methods
178 .iter()
179 .map(|x| x.validate(lib))
180 .collect();
181
182 Ok(Handle::new(Class {
183 declaration: self.declaration.clone(),
184 constructor,
185 destructor,
186 methods: methods?,
187 static_methods: static_methods?,
188 future_methods: async_methods?,
189 doc: self.doc.validate(self.name(), lib)?,
190 destruction_mode: self.destruction_mode.clone(),
191 settings: self.settings.clone(),
192 }))
193 }
194}
195
196impl<T> Class<T>
197where
198 T: DocReference,
199{
200 pub fn name(&self) -> &Name {
201 &self.declaration.name
202 }
203
204 pub fn declaration(&self) -> ClassDeclarationHandle {
205 self.declaration.clone()
206 }
207}
208
209impl Class<Unvalidated> {
210 pub(crate) fn find_method<S: AsRef<str>>(
211 &self,
212 method_name: S,
213 ) -> Option<(Name, FunctionHandle)> {
214 let method_name = method_name.as_ref();
215
216 for method in &self.methods {
217 if method.name.as_ref() == method_name {
218 return Some((method.name.clone(), method.native_function.clone()));
219 }
220 }
221
222 for method in &self.static_methods {
223 if method.name.as_ref() == method_name {
224 return Some((method.name.clone(), method.native_function.clone()));
225 }
226 }
227
228 for async_method in &self.future_methods {
229 if async_method.name.as_ref() == method_name {
230 return Some((
231 async_method.name.clone(),
232 async_method.native_function.clone(),
233 ));
234 }
235 }
236
237 None
238 }
239}
240
241pub type ClassHandle = Handle<Class<Unvalidated>>;
242
243#[derive(Debug)]
245pub struct StaticClass<T>
246where
247 T: DocReference,
248{
249 pub(crate) name: Name,
250 pub(crate) static_methods: Vec<StaticMethod<T>>,
251 pub(crate) doc: Doc<T>,
252}
253
254impl StaticClass<Unvalidated> {
255 pub(crate) fn validate(
256 &self,
257 lib: &LibraryFields,
258 ) -> BindResult<Handle<StaticClass<Validated>>> {
259 let methods: BindResult<Vec<StaticMethod<Validated>>> = self
260 .static_methods
261 .iter()
262 .map(|x| x.validate(lib))
263 .collect();
264 Ok(Handle::new(StaticClass {
265 name: self.name.clone(),
266 static_methods: methods?,
267 doc: self.doc.validate(&self.name, lib)?,
268 }))
269 }
270}
271
272pub type StaticClassHandle = Handle<StaticClass<Unvalidated>>;