oo_bindgen/model/
function.rs

1use std::rc::Rc;
2
3use crate::model::*;
4
5/// Used for iterator "next" functions to get an optional primitive
6#[derive(Debug, Copy, Clone, PartialEq, Eq)]
7pub struct PrimitiveRef {
8    pub(crate) inner: Primitive,
9}
10
11impl PrimitiveRef {
12    pub fn new(inner: Primitive) -> Self {
13        Self { inner }
14    }
15}
16
17/// types that can be returns from native functions
18#[non_exhaustive]
19#[derive(Debug, Clone, PartialEq)]
20pub enum FunctionReturnValue {
21    Basic(BasicType),
22    PrimitiveRef(PrimitiveRef),
23    String(StringType),
24    ClassRef(ClassDeclarationHandle),
25    Struct(UniversalOr<FunctionReturnStructField>),
26    StructRef(UniversalDeclarationOr<FunctionReturnStructField>),
27}
28
29impl From<PrimitiveRef> for FunctionReturnValue {
30    fn from(x: PrimitiveRef) -> Self {
31        FunctionReturnValue::PrimitiveRef(x)
32    }
33}
34
35impl From<Primitive> for FunctionReturnValue {
36    fn from(x: Primitive) -> Self {
37        FunctionReturnValue::Basic(x.into())
38    }
39}
40
41impl From<BasicType> for FunctionReturnValue {
42    fn from(x: BasicType) -> Self {
43        FunctionReturnValue::Basic(x)
44    }
45}
46
47impl From<DurationType> for FunctionReturnValue {
48    fn from(x: DurationType) -> Self {
49        BasicType::Duration(x).into()
50    }
51}
52
53impl From<ClassDeclarationHandle> for FunctionReturnValue {
54    fn from(x: ClassDeclarationHandle) -> Self {
55        FunctionReturnValue::ClassRef(x)
56    }
57}
58
59impl From<StringType> for FunctionReturnValue {
60    fn from(_: StringType) -> Self {
61        FunctionReturnValue::String(StringType)
62    }
63}
64
65impl From<FunctionReturnStructHandle> for FunctionReturnValue {
66    fn from(x: FunctionReturnStructHandle) -> Self {
67        FunctionReturnValue::Struct(x.into())
68    }
69}
70
71impl From<FunctionReturnStructDeclaration> for FunctionReturnValue {
72    fn from(x: FunctionReturnStructDeclaration) -> Self {
73        FunctionReturnValue::StructRef(UniversalDeclarationOr::Specific(x))
74    }
75}
76
77impl From<UniversalStructDeclaration> for FunctionReturnValue {
78    fn from(x: UniversalStructDeclaration) -> Self {
79        FunctionReturnValue::StructRef(UniversalDeclarationOr::Universal(x))
80    }
81}
82
83impl From<Handle<Enum<Unvalidated>>> for FunctionReturnValue {
84    fn from(x: Handle<Enum<Unvalidated>>) -> Self {
85        BasicType::Enum(x).into()
86    }
87}
88
89impl From<UniversalStructHandle> for FunctionReturnValue {
90    fn from(x: UniversalStructHandle) -> Self {
91        Self::Struct(UniversalOr::Universal(x))
92    }
93}
94
95impl From<CollectionClassDeclaration> for FunctionReturnValue {
96    fn from(x: CollectionClassDeclaration) -> Self {
97        Self::ClassRef(x.inner)
98    }
99}
100
101pub type FunctionReturnType<D> = ReturnType<FunctionReturnValue, D>;
102
103/// Types that can be used as native function arguments
104#[non_exhaustive]
105#[derive(Debug, Clone)]
106pub enum FunctionArgument {
107    Basic(BasicType),
108    String(StringType),
109    Collection(CollectionHandle),
110    Struct(UniversalOr<FunctionArgStructField>),
111    StructRef(FunctionArgStructDeclaration),
112    ClassRef(ClassDeclarationHandle),
113    Interface(InterfaceHandle),
114}
115
116impl From<UniversalStructHandle> for FunctionArgument {
117    fn from(x: UniversalStructHandle) -> Self {
118        Self::Struct(UniversalOr::Universal(x))
119    }
120}
121
122impl From<FunctionArgStructHandle> for FunctionArgument {
123    fn from(x: FunctionArgStructHandle) -> Self {
124        Self::Struct(x.into())
125    }
126}
127
128impl From<ClassDeclarationHandle> for FunctionArgument {
129    fn from(x: ClassDeclarationHandle) -> Self {
130        FunctionArgument::ClassRef(x)
131    }
132}
133
134impl From<SynchronousInterface> for FunctionArgument {
135    fn from(x: SynchronousInterface) -> Self {
136        FunctionArgument::Interface(x.inner)
137    }
138}
139
140impl From<AsynchronousInterface> for FunctionArgument {
141    fn from(x: AsynchronousInterface) -> Self {
142        FunctionArgument::Interface(x.inner)
143    }
144}
145
146impl From<Primitive> for FunctionArgument {
147    fn from(x: Primitive) -> Self {
148        FunctionArgument::Basic(BasicType::Primitive(x))
149    }
150}
151
152impl From<StringType> for FunctionArgument {
153    fn from(x: StringType) -> Self {
154        FunctionArgument::String(x)
155    }
156}
157
158impl From<CollectionHandle> for FunctionArgument {
159    fn from(x: CollectionHandle) -> Self {
160        FunctionArgument::Collection(x)
161    }
162}
163
164impl From<FunctionArgStructDeclaration> for FunctionArgument {
165    fn from(x: FunctionArgStructDeclaration) -> Self {
166        FunctionArgument::StructRef(x)
167    }
168}
169
170impl From<UniversalStructDeclaration> for FunctionArgument {
171    fn from(x: UniversalStructDeclaration) -> Self {
172        FunctionArgument::StructRef(FunctionArgStructDeclaration::new(x.inner))
173    }
174}
175
176impl From<BasicType> for FunctionArgument {
177    fn from(x: BasicType) -> Self {
178        FunctionArgument::Basic(x)
179    }
180}
181
182impl From<DurationType> for FunctionArgument {
183    fn from(x: DurationType) -> Self {
184        BasicType::Duration(x).into()
185    }
186}
187
188impl From<Handle<Enum<Unvalidated>>> for FunctionArgument {
189    fn from(x: Handle<Enum<Unvalidated>>) -> Self {
190        BasicType::Enum(x).into()
191    }
192}
193
194impl From<IteratorClassDeclaration> for FunctionArgument {
195    fn from(x: IteratorClassDeclaration) -> Self {
196        Self::ClassRef(x.inner)
197    }
198}
199
200impl From<CollectionClassDeclaration> for FunctionArgument {
201    fn from(x: CollectionClassDeclaration) -> Self {
202        Self::ClassRef(x.inner)
203    }
204}
205
206#[derive(Debug, Copy, Clone, PartialEq, Eq)]
207pub(crate) enum FunctionCategory {
208    Native,
209    CollectionCreate,
210    CollectionDestroy,
211    CollectionAdd,
212    IteratorNext,
213}
214
215/// C function
216#[derive(Debug)]
217pub struct Function<T>
218where
219    T: DocReference,
220{
221    pub(crate) name: Name,
222    pub(crate) category: FunctionCategory,
223    pub(crate) return_type: OptionalReturnType<FunctionReturnValue, T>,
224    pub(crate) arguments: Vec<Arg<FunctionArgument, T>>,
225    pub(crate) error_type: OptionalErrorType<T>,
226    pub(crate) settings: Rc<LibrarySettings>,
227    pub(crate) doc: Doc<T>,
228}
229
230impl Function<Unvalidated> {
231    pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<Handle<Function<Validated>>> {
232        let parameters: BindResult<Vec<Arg<FunctionArgument, Validated>>> =
233            self.arguments.iter().map(|x| x.validate(lib)).collect();
234
235        let arguments: Vec<Name> = self.arguments.iter().map(|x| x.name.clone()).collect();
236
237        Ok(Handle::new(Function {
238            name: self.name.clone(),
239            category: self.category,
240            return_type: self.return_type.validate(&self.name, lib)?,
241            arguments: parameters?,
242            error_type: self.error_type.validate(lib)?,
243            settings: self.settings.clone(),
244            doc: self
245                .doc
246                .validate_with_args(&self.name, lib, Some(&arguments))?,
247        }))
248    }
249}
250
251#[allow(clippy::enum_variant_names)]
252#[derive(Debug, Clone)]
253pub(crate) enum SignatureType {
254    /// function that cannot fail and returns nothing
255    NoErrorNoReturn,
256    /// function that cannot fail and returns something
257    NoErrorWithReturn(FunctionReturnValue, DocString<Validated>),
258    /// function that can fail, but does not return a value
259    ErrorNoReturn(ErrorType<Validated>),
260    /// function that can fail and returns something via an out parameter
261    ErrorWithReturn(
262        ErrorType<Validated>,
263        FunctionReturnValue,
264        DocString<Validated>,
265    ),
266}
267
268impl Function<Validated> {
269    pub(crate) fn get_signature_type(&self) -> SignatureType {
270        match self.error_type.get() {
271            Some(e) => match self.return_type.get() {
272                None => SignatureType::ErrorNoReturn(e.clone()),
273                Some(rt) => {
274                    SignatureType::ErrorWithReturn(e.clone(), rt.value.clone(), rt.doc.clone())
275                }
276            },
277            None => match self.return_type.get() {
278                None => SignatureType::NoErrorNoReturn,
279                Some(rt) => SignatureType::NoErrorWithReturn(rt.value.clone(), rt.doc.clone()),
280            },
281        }
282    }
283}
284
285pub type FunctionHandle = Handle<Function<Unvalidated>>;
286
287/// represents a method that initiates an asynchronous operation
288/// an eventually completes an abstract future
289#[derive(Debug, Clone)]
290pub struct FutureMethod<T>
291where
292    T: DocReference,
293{
294    pub(crate) name: Name,
295    pub(crate) associated_class: Handle<ClassDeclaration>,
296    pub(crate) future: FutureInterface<T>,
297    pub(crate) native_function: Handle<Function<T>>,
298}
299
300impl FutureMethod<Validated> {
301    pub fn arguments(&self) -> impl Iterator<Item = &Arg<FunctionArgument, Validated>> {
302        self.native_function.arguments.iter().skip(1)
303    }
304
305    pub fn arguments_without_callback(
306        &self,
307    ) -> impl Iterator<Item = &Arg<FunctionArgument, Validated>> {
308        self.arguments().filter(|param| match &param.arg_type {
309            FunctionArgument::Interface(handle) => handle.name != self.future.interface.name,
310            _ => true,
311        })
312    }
313}
314
315impl FutureMethod<Unvalidated> {
316    pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<FutureMethod<Validated>> {
317        Ok(FutureMethod {
318            name: self.name.clone(),
319            associated_class: self.associated_class.clone(),
320            future: self.future.validate(lib)?,
321            native_function: self.native_function.validate(lib)?,
322        })
323    }
324}
325
326pub type FutureMethodHandle = FutureMethod<Unvalidated>;
327
328#[derive(Debug, Clone)]
329pub struct ClassDestructor<T>
330where
331    T: DocReference,
332{
333    pub(crate) class: ClassDeclarationHandle,
334    pub(crate) function: Handle<Function<T>>,
335}
336
337impl ClassDestructor<Unvalidated> {
338    pub(crate) fn new(
339        lib: &mut LibraryBuilder,
340        class: ClassDeclarationHandle,
341        doc: Doc<Unvalidated>,
342    ) -> BindResult<Self> {
343        let destructor_function_name = class
344            .name
345            .append(&lib.settings().class.class_destructor_suffix);
346        let instance_name = lib.settings().class.method_instance_argument_name.clone();
347
348        let function = lib
349            .define_function(destructor_function_name)?
350            .param(
351                instance_name,
352                class.clone(),
353                format!("Instance of {{class:{}}} to destroy", class.name),
354            )?
355            .doc(doc)?
356            .build()?;
357
358        Ok(Self { class, function })
359    }
360
361    pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<ClassDestructor<Validated>> {
362        Ok(ClassDestructor {
363            class: self.class.clone(),
364            function: self.function.validate(lib)?,
365        })
366    }
367}
368
369#[derive(Debug, Clone)]
370pub struct ClassConstructor<T>
371where
372    T: DocReference,
373{
374    pub(crate) class: ClassDeclarationHandle,
375    pub(crate) function: Handle<Function<T>>,
376}
377
378impl ClassConstructor<Unvalidated> {
379    pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<ClassConstructor<Validated>> {
380        Ok(ClassConstructor {
381            class: self.class.clone(),
382            function: self.function.validate(lib)?,
383        })
384    }
385
386    pub(crate) fn new(
387        class: ClassDeclarationHandle,
388        function: Handle<Function<Unvalidated>>,
389    ) -> Self {
390        Self { class, function }
391    }
392}