oo_bindgen/model/builder/
function.rs1use crate::model::*;
2
3pub struct FunctionBuilder<'a> {
4 lib: &'a mut LibraryBuilder,
5 name: Name,
6 function_type: FunctionCategory,
7 return_type: OptionalReturnType<FunctionReturnValue, Unvalidated>,
8 params: Vec<Arg<FunctionArgument, Unvalidated>>,
9 doc: OptionalDoc,
10 error_type: OptionalErrorType<Unvalidated>,
11}
12
13impl<'a> FunctionBuilder<'a> {
14 pub(crate) fn new(
15 lib: &'a mut LibraryBuilder,
16 name: Name,
17 function_type: FunctionCategory,
18 ) -> Self {
19 Self {
20 lib,
21 name: name.clone(),
22 function_type,
23 return_type: OptionalReturnType::new(),
24 params: Vec::new(),
25 doc: OptionalDoc::new(name),
26 error_type: OptionalErrorType::new(),
27 }
28 }
29
30 pub fn param<T: IntoName, D: Into<DocString<Unvalidated>>, P: Into<FunctionArgument>>(
31 mut self,
32 name: T,
33 param_type: P,
34 doc: D,
35 ) -> BindResult<Self> {
36 let param_type = param_type.into();
37 let name = name.into_name()?;
38 self.params.push(Arg {
39 name,
40 arg_type: param_type,
41 doc: doc.into(),
42 });
43 Ok(self)
44 }
45
46 pub fn returns<D: Into<DocString<Unvalidated>>, T: Into<FunctionReturnValue>>(
47 mut self,
48 return_type: T,
49 doc: D,
50 ) -> BindResult<Self> {
51 self.return_type
52 .set(&self.name, return_type.into(), doc.into())?;
53 Ok(self)
54 }
55
56 pub fn fails_with(mut self, err: ErrorType<Unvalidated>) -> BindResult<Self> {
57 self.error_type.set(&self.name, &err)?;
58 Ok(self)
59 }
60
61 pub fn doc<D: Into<Doc<Unvalidated>>>(mut self, doc: D) -> BindResult<Self> {
62 self.doc.set(doc.into())?;
63 Ok(self)
64 }
65
66 pub fn build(self) -> BindResult<FunctionHandle> {
67 let handle = Handle::new(Function {
68 name: self.name,
69 category: self.function_type,
70 return_type: self.return_type,
71 arguments: self.params,
72 error_type: self.error_type,
73 settings: self.lib.clone_settings(),
74 doc: self.doc.extract()?,
75 });
76
77 self.lib
78 .add_statement(Statement::FunctionDefinition(handle.clone()))?;
79
80 Ok(handle)
81 }
82
83 pub fn build_static<N: IntoName>(self, name: N) -> BindResult<StaticMethod<Unvalidated>> {
85 let handle = self.build()?;
86 Ok(StaticMethod {
87 name: name.into_name()?,
88 native_function: handle,
89 })
90 }
91
92 pub fn build_static_with_same_name(self) -> BindResult<StaticMethod<Unvalidated>> {
94 let handle = self.build()?;
95 Ok(StaticMethod {
96 name: handle.name.clone(),
97 native_function: handle,
98 })
99 }
100}
101
102pub struct ClassMethodBuilder<'a> {
103 method_name: Name,
104 class: ClassDeclarationHandle,
105 inner: FunctionBuilder<'a>,
106}
107
108impl<'a> ClassMethodBuilder<'a> {
109 pub(crate) fn new(
110 lib: &'a mut LibraryBuilder,
111 method_name: Name,
112 class: ClassDeclarationHandle,
113 ) -> BindResult<Self> {
114 if method_name.contains(class.name.as_ref()) {
115 return Err(BindingErrorVariant::BadMethodName { class, method_name }.into());
116 }
117
118 let instance_arg_name = lib.settings().class.method_instance_argument_name.clone();
119
120 let builder = lib
121 .define_function(class.name.append(&method_name))?
122 .param(
123 instance_arg_name,
124 class.clone(),
125 format!("Instance of {{class:{}}}", class.name),
126 )?;
127
128 Ok(Self {
129 method_name,
130 class,
131 inner: builder,
132 })
133 }
134
135 pub fn param<T: IntoName, D: Into<DocString<Unvalidated>>, P: Into<FunctionArgument>>(
136 self,
137 name: T,
138 param_type: P,
139 doc: D,
140 ) -> BindResult<Self> {
141 Ok(Self {
142 method_name: self.method_name,
143 class: self.class,
144 inner: self.inner.param(name, param_type, doc)?,
145 })
146 }
147
148 pub fn returns<D: Into<DocString<Unvalidated>>, T: Into<FunctionReturnValue>>(
149 self,
150 return_type: T,
151 doc: D,
152 ) -> BindResult<Self> {
153 let return_type = return_type.into();
154 let doc = doc.into();
155 Ok(Self {
156 method_name: self.method_name,
157 class: self.class,
158 inner: self.inner.returns(return_type, doc)?,
159 })
160 }
161
162 pub fn fails_with(self, err: ErrorType<Unvalidated>) -> BindResult<Self> {
163 Ok(Self {
164 method_name: self.method_name,
165 class: self.class,
166 inner: self.inner.fails_with(err)?,
167 })
168 }
169
170 pub fn doc<D: Into<Doc<Unvalidated>>>(self, doc: D) -> BindResult<Self> {
171 Ok(Self {
172 method_name: self.method_name,
173 class: self.class,
174 inner: self.inner.doc(doc)?,
175 })
176 }
177
178 pub fn build(self) -> BindResult<Method<Unvalidated>> {
179 let function = self.inner.build()?;
180 Ok(Method::new(self.method_name, self.class, function))
181 }
182}
183
184pub struct ClassConstructorBuilder<'a> {
185 class: ClassDeclarationHandle,
186 inner: FunctionBuilder<'a>,
187}
188
189impl<'a> ClassConstructorBuilder<'a> {
190 pub(crate) fn new(
191 lib: &'a mut LibraryBuilder,
192 class: ClassDeclarationHandle,
193 ) -> BindResult<Self> {
194 let builder = lib
195 .define_function(
196 class
197 .name
198 .append(&lib.settings().class.class_constructor_suffix),
199 )?
200 .returns(
201 class.clone(),
202 format!("Instance of {{class:{}}}", class.name),
203 )?;
204
205 Ok(Self {
206 class,
207 inner: builder,
208 })
209 }
210
211 pub fn param<T: IntoName, D: Into<DocString<Unvalidated>>, P: Into<FunctionArgument>>(
212 self,
213 name: T,
214 param_type: P,
215 doc: D,
216 ) -> BindResult<Self> {
217 Ok(Self {
218 class: self.class,
219 inner: self.inner.param(name, param_type, doc)?,
220 })
221 }
222
223 pub fn fails_with(self, err: ErrorType<Unvalidated>) -> BindResult<Self> {
224 Ok(Self {
225 class: self.class,
226 inner: self.inner.fails_with(err)?,
227 })
228 }
229
230 pub fn doc<D: Into<Doc<Unvalidated>>>(self, doc: D) -> BindResult<Self> {
231 Ok(Self {
232 class: self.class,
233 inner: self.inner.doc(doc)?,
234 })
235 }
236
237 pub fn build(self) -> BindResult<ClassConstructor<Unvalidated>> {
238 Ok(ClassConstructor::new(self.class, self.inner.build()?))
239 }
240}
241
242pub struct FutureMethodBuilder<'a> {
243 future: FutureInterface<Unvalidated>,
244 inner: ClassMethodBuilder<'a>,
245}
246
247impl<'a> FutureMethodBuilder<'a> {
248 pub(crate) fn new(
249 lib: &'a mut LibraryBuilder,
250 method_name: Name,
251 class: ClassDeclarationHandle,
252 future: FutureInterface<Unvalidated>,
253 ) -> BindResult<Self> {
254 let builder = lib.define_method(method_name, class)?;
255
256 Ok(Self {
257 future,
258 inner: builder,
259 })
260 }
261
262 pub fn param<T: IntoName, D: Into<DocString<Unvalidated>>, P: Into<FunctionArgument>>(
263 self,
264 name: T,
265 param_type: P,
266 doc: D,
267 ) -> BindResult<Self> {
268 let name = name.into_name()?;
269 let param_type = param_type.into();
270 let builder = self.inner.param(name, param_type, doc)?;
271 Ok(Self {
272 future: self.future,
273 inner: builder,
274 })
275 }
276
277 pub fn fails_with(self, err: ErrorType<Unvalidated>) -> BindResult<Self> {
278 Ok(Self {
279 future: self.future,
280 inner: self.inner.fails_with(err)?,
281 })
282 }
283
284 pub fn doc<D: Into<Doc<Unvalidated>>>(self, doc: D) -> BindResult<Self> {
285 Ok(Self {
286 future: self.future,
287 inner: self.inner.doc(doc)?,
288 })
289 }
290
291 pub fn build(self) -> BindResult<FutureMethod<Unvalidated>> {
292 let future = self.future.clone();
293 let callback_parameter_name = self
294 .inner
295 .inner
296 .lib
297 .settings()
298 .future
299 .async_method_callback_parameter_name
300 .clone();
301 let method = self
302 .inner
303 .param(
304 callback_parameter_name,
305 FunctionArgument::Interface(self.future.interface),
306 "callback invoked when the operation completes",
307 )?
308 .build()?;
309
310 Ok(FutureMethod {
311 name: method.name,
312 associated_class: method.associated_class,
313 future,
314 native_function: method.native_function,
315 })
316 }
317}