oo_bindgen/model/builder/
class.rs1use crate::model::*;
2
3pub struct ClassBuilder<'a> {
4 lib: &'a mut LibraryBuilder,
5 declaration: ClassDeclarationHandle,
6 constructor: Option<ClassConstructor<Unvalidated>>,
7 destructor: Option<ClassDestructor<Unvalidated>>,
8 methods: Vec<Method<Unvalidated>>,
9 static_methods: Vec<StaticMethod<Unvalidated>>,
10 async_methods: Vec<FutureMethod<Unvalidated>>,
11 doc: Option<Doc<Unvalidated>>,
12 destruction_mode: DestructionMode,
13}
14
15impl<'a> ClassBuilder<'a> {
16 pub(crate) fn new(lib: &'a mut LibraryBuilder, declaration: ClassDeclarationHandle) -> Self {
17 Self {
18 lib,
19 declaration,
20 constructor: None,
21 destructor: None,
22 methods: Vec::new(),
23 static_methods: Vec::new(),
24 async_methods: Vec::new(),
25 doc: None,
26 destruction_mode: DestructionMode::Automatic,
27 }
28 }
29
30 pub fn doc<D: Into<Doc<Unvalidated>>>(mut self, doc: D) -> BindResult<Self> {
31 match self.doc {
32 None => {
33 self.doc = Some(doc.into());
34 Ok(self)
35 }
36 Some(_) => Err(BindingErrorVariant::DocAlreadyDefined {
37 symbol_name: self.declaration.name.clone(),
38 }
39 .into()),
40 }
41 }
42
43 pub fn constructor(mut self, constructor: ClassConstructor<Unvalidated>) -> BindResult<Self> {
44 self.check_class(&constructor.function.name, constructor.class.clone())?;
46
47 if self.constructor.is_some() {
48 return Err(BindingErrorVariant::ConstructorAlreadyDefined {
49 handle: self.declaration,
50 }
51 .into());
52 }
53
54 self.constructor = Some(constructor);
55
56 Ok(self)
57 }
58
59 pub fn destructor(mut self, destructor: ClassDestructor<Unvalidated>) -> BindResult<Self> {
60 if self.destructor.is_some() {
61 return Err(BindingErrorVariant::DestructorAlreadyDefined {
62 handle: self.declaration,
63 }
64 .into());
65 }
66
67 self.check_class(&destructor.function.name, destructor.class.clone())?;
69
70 self.destructor = Some(destructor);
71
72 Ok(self)
73 }
74
75 pub fn method(mut self, method: Method<Unvalidated>) -> BindResult<Self> {
76 self.check_class(&method.name, method.associated_class.clone())?;
78
79 self.methods.push(method);
80
81 Ok(self)
82 }
83
84 pub fn static_method(mut self, method: StaticMethod<Unvalidated>) -> BindResult<Self> {
85 self.static_methods.push(method);
86 Ok(self)
87 }
88
89 fn check_class(&self, name: &Name, other: ClassDeclarationHandle) -> BindResult<()> {
90 if self.declaration != other {
91 return Err(BindingErrorVariant::ClassMemberWrongAssociatedClass {
92 name: name.clone(),
93 declared: other,
94 added_to: self.declaration.clone(),
95 }
96 .into());
97 }
98 Ok(())
99 }
100
101 pub fn async_method(mut self, method: FutureMethod<Unvalidated>) -> BindResult<Self> {
102 self.check_class(&method.name, method.associated_class.clone())?;
103
104 self.async_methods.push(method);
105
106 Ok(self)
107 }
108
109 pub fn custom_destroy<T: IntoName>(mut self, name: T) -> BindResult<Self> {
110 if self.destructor.is_none() {
111 return Err(BindingErrorVariant::NoDestructorForManualDestruction {
112 handle: self.declaration,
113 }
114 .into());
115 }
116
117 self.destruction_mode = DestructionMode::Custom(name.into_name()?);
118 Ok(self)
119 }
120
121 pub fn disposable_destroy(mut self) -> BindResult<Self> {
122 if self.destructor.is_none() {
123 return Err(BindingErrorVariant::NoDestructorForManualDestruction {
124 handle: self.declaration,
125 }
126 .into());
127 }
128
129 self.destruction_mode = DestructionMode::Dispose;
130 Ok(self)
131 }
132
133 pub fn build(self) -> BindResult<ClassHandle> {
134 let doc = match self.doc {
135 Some(doc) => doc,
136 None => {
137 return Err(BindingErrorVariant::DocNotDefined {
138 symbol_name: self.declaration.name.clone(),
139 }
140 .into())
141 }
142 };
143
144 let handle = Handle::new(Class {
145 declaration: self.declaration.clone(),
146 constructor: self.constructor,
147 destructor: self.destructor,
148 methods: self.methods,
149 static_methods: self.static_methods,
150 future_methods: self.async_methods,
151 doc,
152 destruction_mode: self.destruction_mode,
153 settings: self.lib.clone_settings(),
154 });
155
156 self.lib
157 .add_statement(Statement::ClassDefinition(handle.clone()))?;
158
159 Ok(handle)
160 }
161}
162
163pub struct StaticClassBuilder<'a> {
164 lib: &'a mut LibraryBuilder,
165 name: Name,
166 static_methods: Vec<StaticMethod<Unvalidated>>,
167 doc: OptionalDoc,
168}
169
170impl<'a> StaticClassBuilder<'a> {
171 pub(crate) fn new(lib: &'a mut LibraryBuilder, name: Name) -> Self {
172 Self {
173 lib,
174 name: name.clone(),
175 static_methods: Vec::new(),
176 doc: OptionalDoc::new(name),
177 }
178 }
179
180 pub fn doc<D: Into<Doc<Unvalidated>>>(mut self, doc: D) -> BindResult<Self> {
181 self.doc.set(doc.into())?;
182 Ok(self)
183 }
184
185 pub fn static_method(mut self, method: StaticMethod<Unvalidated>) -> BindResult<Self> {
186 self.static_methods.push(method);
187 Ok(self)
188 }
189
190 pub fn build(self) -> BindResult<StaticClassHandle> {
191 let handle = Handle::new(StaticClass {
192 name: self.name,
193 static_methods: self.static_methods,
194 doc: self.doc.extract()?,
195 });
196
197 self.lib
198 .add_statement(Statement::StaticClassDefinition(handle.clone()))?;
199
200 Ok(handle)
201 }
202}