rusty_bind_parser/
binding_module.rs

1//
2// Wildland Project
3//
4// Copyright © 2022 Golem Foundation,
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License version 3 as published by
8// the Free Software Foundation.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18use std::collections::HashSet;
19
20use proc_macro2::{Ident, Span, TokenStream};
21use quote::quote;
22use syn::token::Comma;
23use syn::{
24    parse_quote,
25    parse_str,
26    Abi,
27    Field,
28    Item,
29    ItemEnum,
30    ItemForeignMod,
31    ItemMod,
32    Type,
33    Variant,
34};
35
36use crate::ffi_helper_traits::get_ffi_helper_trait;
37use crate::trait_function_helpers::get_trait_functions;
38use crate::utils::BuildContext;
39use crate::DROP_FUNCTION_SYMBOL_NAME;
40/// An implementation of a translator that can parse some specific Rust modules and
41/// prepare extern functions that are part of the static library interface.
42///
43use crate::{
44    binding_types::*,
45    cpp::{generate_cpp_file, swig_generator::generate_swig_based_on_wrappers},
46    enum_helpers::*,
47    extern_functions_utils::*,
48    extern_module_translator::ExternModuleTranslator,
49    swift::{generate_c_externs_file, generate_swift_file},
50    EXPORTED_SYMBOLS_PREFIX,
51};
52
53pub struct GeneratedFilesContent {
54    pub cpp_header: String,
55    pub swift_header: String,
56    pub cpp_externs: String,
57    pub swig_interface: String,
58}
59
60// Feature names that are read from std::env::vars are uppercased and every '-' is replaced by '_'.
61// This class guarantees that the same transformation will be applied to every feature name regardless its origin.
62#[derive(Debug, Clone)]
63pub struct CargoFeature {
64    val: String,
65}
66
67impl CargoFeature {
68    pub fn new<T>(val: &T) -> Self
69    where
70        T: AsRef<str> + ?Sized,
71    {
72        Self {
73            val: val.as_ref().to_uppercase().replace('-', "_"),
74        }
75    }
76}
77
78impl PartialEq for CargoFeature {
79    fn eq(&self, other: &Self) -> bool {
80        self.val == other.val
81    }
82}
83
84/// The structure consist of:
85/// - extern blocks translator module, i.e. `extern "Rust"` and `extern "Traits"`,
86/// - generated extern functions that wrap the actual user's methods.
87///
88pub struct BindingModule {
89    extern_module_translator: ExternModuleTranslator,
90    wrappers_impls: TokenStream,
91    extern_functions: Vec<ExternFunction>,
92}
93
94impl BindingModule {
95    /// The method translates Rust module containing `extern "Rust"` and generates all
96    /// needed wrappers.
97    ///
98    pub fn translate_module(module: ItemMod, context: &BuildContext) -> anyhow::Result<Self> {
99        let enums: HashSet<ItemEnum> = get_enums_from_module(&module, context)?
100            .into_iter()
101            .collect();
102
103        let module_name = &module.ident;
104        let mut extern_module_translator = ExternModuleTranslator::new(enums.clone());
105        if let Some(ext_rust_module) = BindingModule::get_extern_mod_from_module(&module, "Rust") {
106            extern_module_translator.parse_items_in_extern_rust_module(ext_rust_module, context)?;
107        }
108        if let Some(ext_trait_module) = BindingModule::get_extern_mod_from_module(&module, "Traits")
109        {
110            extern_module_translator.translate_trait_external_modules(ext_trait_module, context)?;
111        }
112        if let Some(ext_exception_trait_module) =
113            BindingModule::get_extern_mod_from_module(&module, "ExceptionTrait")
114        {
115            extern_module_translator
116                .translate_exception_trait_external_module(ext_exception_trait_module, context)?;
117        }
118
119        let mut result = BindingModule {
120            extern_module_translator,
121            wrappers_impls: Default::default(),
122            extern_functions: Default::default(),
123        };
124        result.create_wrappers_for_custom_types();
125        result.create_complex_enum_getters(&enums);
126        result.create_wrappers_for_exception_trait();
127        result.create_wrappers_for_traits();
128        result.create_wrappers_for_global_functions();
129        result.create_wrappers_for_results(enums)?;
130        result.create_wrappers_for_builtins()?;
131        result.create_wrappers_for_clones();
132        result.create_wrappers_for_strings()?;
133        result.assign_trait_impls();
134        result.add_ffi_helper_traits();
135        result.wrappers_impls.extend(
136            result
137                .extern_functions
138                .iter()
139                .map(|extern_function| extern_function.tokens.clone()),
140        );
141        // Panic wrapper needs to be registered as en extern function but it's call should not be put into the `interface.rs`
142        // that's why it should be registered after all extern functions have been added to the `wrappers_impls`
143        result.register_panic_wrapper();
144        let wrappers_impls = &result.wrappers_impls;
145        result.wrappers_impls = quote!( mod #module_name { #![allow(warnings, unused)] use super::*; #wrappers_impls } );
146        Ok(result)
147    }
148
149    /// Method generates C++, Swift and SWIG glue code. The latter is needed to generate glue code
150    /// for other target languages like Java, C#, Python etc.
151    ///
152    pub fn generate_binding_files(&self) -> GeneratedFilesContent {
153        GeneratedFilesContent {
154            cpp_header: generate_cpp_file(&self.extern_module_translator, &self.extern_functions),
155            swift_header: generate_swift_file(&self.extern_module_translator),
156            cpp_externs: generate_c_externs_file(
157                &self.extern_module_translator,
158                &self.extern_functions,
159            ),
160            swig_interface: generate_swig_based_on_wrappers(&self.extern_module_translator),
161        }
162    }
163
164    /// Returns the whole generated code in the form of a token stream.
165    /// It wraps the derived module into another one in order to avoid custom types
166    /// and wrappers types names collision.
167    ///
168    pub fn get_tokens(&self) -> TokenStream {
169        self.wrappers_impls.clone()
170    }
171
172    /// Helper method - returns a foreign module from within the Rust module.
173    ///
174    fn get_extern_mod_from_module<'a>(
175        module: &'a ItemMod,
176        extern_lang: &str,
177    ) -> Option<&'a ItemForeignMod> {
178        module.content.as_ref().and_then(|(_, items)| {
179            items.iter().find_map(|module_item| match module_item {
180                Item::ForeignMod(
181                    rust_module @ ItemForeignMod {
182                        abi:
183                            Abi {
184                                name: Some(lang), ..
185                            },
186                        ..
187                    },
188                ) if lang.value() == extern_lang => Some(rust_module),
189                _ => None,
190            })
191        })
192    }
193
194    fn register_extern_function(&mut self, function: ExternFunction) {
195        self.extern_functions.push(function);
196    }
197
198    fn register_panic_wrapper(&mut self) {
199        let ex_fn = ExternFunction {
200            arguments: vec![WrapperType {
201                original_type_name: syn::parse_str("String").unwrap(),
202                wrapper_name: "String".to_string(),
203                rust_type: RustWrapperType::Custom,
204                reference_parameters: Some(ReferenceParameters {
205                    is_static: true,
206                    is_mut: false,
207                    boxed: false,
208                }),
209                impl_traits: vec![],
210            }],
211            return_type: None,
212            name: format!("{}$fatalError", EXPORTED_SYMBOLS_PREFIX),
213            tokens: parse_str("panic!(message);").unwrap(),
214        };
215        self.extern_functions.push(ex_fn);
216    }
217
218    fn create_complex_enum_getters(&mut self, enums: &HashSet<ItemEnum>) {
219        enums
220            .iter()
221            .filter(|enum_item| !is_primitive_enum(enum_item))
222            .for_each(|ce| self.complex_enum_getter(ce));
223    }
224
225    fn complex_enum_getter(&mut self, complex_enum: &ItemEnum) {
226        let enum_ident = &complex_enum.ident;
227        let variant_wrapper_structs = complex_enum
228            .variants
229            .iter()
230            .map(|v| self.create_variant_struct_wrapper(v, complex_enum))
231            .collect::<TokenStream>();
232        let many_fields_variants_wrapper_getters =
233            self.create_and_register_many_fields_variants_wrapper_getters(complex_enum);
234        let single_field_variants_getters =
235            self.create_and_register_single_field_variants_wrapper_getters(complex_enum);
236
237        if complex_enum
238            .variants
239            .iter()
240            .any(|v| !is_ignored_variant(v) && !is_unit_variant(v))
241        {
242            let enum_impl_block = quote! {
243                impl #enum_ident {
244                    #many_fields_variants_wrapper_getters
245                    #single_field_variants_getters
246                }
247            };
248            self.wrappers_impls.extend(variant_wrapper_structs);
249            self.wrappers_impls.extend(enum_impl_block);
250        }
251    }
252
253    fn create_and_register_many_fields_variants_wrapper_getters(
254        &mut self,
255        complex_enum: &ItemEnum,
256    ) -> TokenStream {
257        let enum_ident = &complex_enum.ident;
258        complex_enum
259            .variants
260            .iter()
261            .filter(|v| is_many_fields_variant(v))
262            .map(|v| {
263                let getter_name = variant_getter_ident(v);
264                let wrapper_name = variant_wrapper_ident(enum_ident, &v.ident);
265                self.register_variant_getter_extern_function(complex_enum, v);
266                quote! {fn #getter_name(&self) -> #wrapper_name {
267                    #wrapper_name(self.clone())
268                }}
269            })
270            .collect::<TokenStream>()
271    }
272
273    fn create_and_register_single_field_variants_wrapper_getters(
274        &mut self,
275        complex_enum: &ItemEnum,
276    ) -> TokenStream {
277        complex_enum
278            .variants
279            .iter()
280            .filter(|v| is_single_field_variant(v))
281            .filter_map(|v| {
282                let field = &get_fields(v).unwrap()[0];
283                let variant_ident = &v.ident;
284                match &field_type(field) {
285                    FieldType::Type(field_type) => {
286                        let return_type: Ident = syn::parse_str(field_type).unwrap();
287                        let fn_ident = variant_getter_ident(v);
288                        let field_retrieve = if is_primitive_field(field) {
289                            quote! {*field}
290                        } else {
291                            quote! {field.clone()}
292                        };
293                        let field_match = if let Some(name) = field_name(field) {
294                            let name = syn::parse_str::<Ident>(&name).unwrap();
295                            quote! {{#name: field}}
296                        } else {
297                            quote! {(field)}
298                        };
299                        self.register_variant_getter_extern_function(complex_enum, v);
300                        Some(quote! {
301                            fn #fn_ident(&self) -> #return_type {
302                                match &self {
303                                    Self::#variant_ident #field_match => #field_retrieve,
304                                    _ => panic!(),
305                                }
306                            }
307                        })
308                    }
309                    FieldType::Ignored => None,
310                }
311            })
312            .collect::<TokenStream>()
313    }
314
315    fn create_variant_struct_wrapper(
316        &mut self,
317        variant: &Variant,
318        enum_item: &ItemEnum,
319    ) -> TokenStream {
320        let enum_ident = &enum_item.ident;
321        let wrapper_ident = variant_wrapper_ident(enum_ident, &variant.ident);
322        let struct_tokens = quote! {#[derive(Clone)] pub struct #wrapper_ident(#enum_ident);};
323        get_fields(variant)
324            .map(|fields| {
325                if fields.len() > 1 {
326                    let field_getters =
327                        self.create_and_register_variant_fields_getters(fields, enum_item, variant);
328                    self.register_drop_function_for_variant_wrapper(wrapper_ident.to_string());
329                    self.register_clone_function_for_variant_wrapper(wrapper_ident.to_string());
330                    quote! {
331                        #struct_tokens
332                        impl #wrapper_ident {
333                            #field_getters
334                        }
335                    }
336                } else {
337                    // variants with only one field are returned directly, without a wrapper
338                    // unit variants are not returned at all
339                    quote! {}
340                }
341            })
342            .unwrap_or_default()
343    }
344
345    fn register_drop_function_for_variant_wrapper(&mut self, wrapper_name: String) {
346        let ext_fun = create_drop_extern_function(WrapperType {
347            original_type_name: syn::parse_str(&wrapper_name).unwrap(),
348            wrapper_name,
349            rust_type: RustWrapperType::Custom,
350            reference_parameters: None,
351            impl_traits: vec![],
352        });
353        self.register_extern_function(ext_fun);
354    }
355
356    fn register_clone_function_for_variant_wrapper(&mut self, wrapper_name: String) {
357        let ext_fun = create_clone_extern_function(WrapperType {
358            original_type_name: syn::parse_str(&wrapper_name).unwrap(),
359            wrapper_name,
360            rust_type: RustWrapperType::Custom,
361            reference_parameters: None,
362            impl_traits: vec![],
363        });
364        self.register_extern_function(ext_fun);
365    }
366
367    fn create_and_register_variant_fields_getters(
368        &mut self,
369        fields: &syn::punctuated::Punctuated<syn::Field, Comma>,
370        enum_item: &ItemEnum,
371        variant: &Variant,
372    ) -> TokenStream {
373        fields
374            .iter()
375            .enumerate()
376            .map(|(idx, field)| {
377                let field_type = field_type(field).unwrap_type();
378                let return_type: TokenStream = field_type.parse().unwrap();
379                let fn_ident = field_getter_ident(field, idx);
380                let (fields_match, field_name) = if let Some(field_name) = &field.ident {
381                    (quote! {{#field_name, ..}}, field_name.clone())
382                } else {
383                    let fields_match = (0..fields.len())
384                        .map(|idx| format!("_{idx}"))
385                        .collect::<Vec<_>>()
386                        .join(", ")
387                        .parse::<TokenStream>()
388                        .unwrap();
389                    (
390                        quote! {(#fields_match)},
391                        Ident::new(&format!("_{idx}"), Span::call_site()),
392                    )
393                };
394
395                self.register_field_getter_extern_function(enum_item, variant, field, idx);
396
397                let variant_ident = &variant.ident;
398                let enum_ident = &enum_item.ident;
399                quote! {
400                    fn #fn_ident(&self) -> #return_type {
401                        match &self.0 {
402                            #enum_ident::#variant_ident #fields_match => (*#field_name).clone(),
403                            _ => panic!(),
404                        }
405                    }
406                }
407            })
408            .collect::<TokenStream>()
409    }
410
411    fn register_field_getter_extern_function(
412        &mut self,
413        enum_item: &ItemEnum,
414        variant: &Variant,
415        field: &Field,
416        field_idx: usize,
417    ) {
418        let function = create_field_getter_function(enum_item, variant, field, field_idx);
419        let extern_function = create_extern_function_for_custom_type(
420            variant_wrapper_ident(&enum_item.ident, &variant.ident)
421                .to_string()
422                .as_str(),
423            &function,
424        );
425        self.register_extern_function(extern_function);
426    }
427
428    fn register_variant_getter_extern_function(&mut self, enum_item: &ItemEnum, variant: &Variant) {
429        let function = create_variant_getter_function(enum_item, variant);
430        if let Some(function) = function {
431            let extern_function = create_extern_function_for_custom_type(
432                enum_item.ident.to_string().as_str(),
433                &function,
434            );
435            self.register_extern_function(extern_function);
436        }
437    }
438
439    fn assign_trait_impls(&mut self) {
440        let declared_impls = self.extern_module_translator.declared_impls.to_owned();
441        for (type_, traits) in declared_impls {
442            if let Some(wt) = self
443                .extern_module_translator
444                .user_custom_types
445                .to_owned()
446                .into_keys()
447                .find(|wt| wt.wrapper_name == *type_)
448            {
449                let (mut wt, funcs) = self
450                    .extern_module_translator
451                    .user_custom_types
452                    .remove_entry(&wt)
453                    .unwrap();
454
455                for trait_ in traits {
456                    if let Some(funcs) =
457                        get_trait_functions(wt.wrapper_name.to_owned(), trait_.to_owned())
458                    {
459                        funcs.iter().for_each(|function| {
460                            self.register_extern_function(create_extern_function_for_custom_type(
461                                &wt.wrapper_name,
462                                function,
463                            ))
464                        });
465                        wt.impl_traits.push(RustTrait {
466                            name: trait_.to_owned(),
467                            has_methods: !funcs.is_empty(),
468                        });
469                    }
470                }
471
472                self.extern_module_translator
473                    .user_custom_types
474                    .insert(wt, funcs);
475            }
476        }
477    }
478
479    fn add_ffi_helper_traits(&mut self) {
480        let mut all_impl_traits: HashSet<String> = HashSet::new();
481        for (_, traits) in self.extern_module_translator.declared_impls.iter() {
482            all_impl_traits.extend(traits.clone());
483        }
484
485        for trait_ in all_impl_traits {
486            if let Some(definition) = get_ffi_helper_trait(trait_) {
487                self.wrappers_impls.extend(definition);
488            }
489        }
490    }
491
492    fn create_wrappers_for_custom_types(&mut self) {
493        self.extern_module_translator
494            .user_custom_types
495            .iter()
496            .flat_map(|(custom_type, functions)| match custom_type {
497                WrapperType {
498                    original_type_name: _,
499                    wrapper_name,
500                    rust_type:
501                        RustWrapperType::Custom | RustWrapperType::ArcMutex | RustWrapperType::Arc,
502                    ..
503                } => functions
504                    .iter()
505                    .map(|function| create_extern_function_for_custom_type(wrapper_name, function))
506                    .collect(),
507                _ => vec![],
508            })
509            .collect::<Vec<_>>()
510            .into_iter()
511            .for_each(|f| self.register_extern_function(f));
512    }
513
514    fn create_wrappers_for_results(&mut self, enums: HashSet<ItemEnum>) -> anyhow::Result<()> {
515        self.extern_module_translator
516            .rust_types_wrappers.clone()
517            .unordered_iter()
518            .map(|wrapper| match wrapper {
519                WrapperType {
520                    original_type_name,
521                    wrapper_name,
522                    rust_type: RustWrapperType::Result(ok_wrapper_type, exceptions_wrapper_type),
523                    ..
524                } => {
525                    let mut local_extern_mod_translator = ExternModuleTranslator::new(enums.clone());
526                    let ok_type = &ok_wrapper_type.original_type_name;
527                    let exc_type = &exceptions_wrapper_type.original_type_name;
528                    let from_ok_extern_function = from_ok_extern_function(wrapper, ok_wrapper_type);
529                    let from_err_extern_function = from_err_extern_function(wrapper, exceptions_wrapper_type);
530                    let (_, is_ok_function) = local_extern_mod_translator
531                        .translate_function(&parse_quote! { fn is_ok(self: &#original_type_name) -> bool; })?;
532                    let is_ok_extern_function = create_extern_function_for_custom_type(
533                        wrapper_name,
534                        &is_ok_function,
535                    );
536                    let (_, unwrap_unchecked_function) = local_extern_mod_translator
537                        .translate_function(
538                            &parse_quote! { fn unwrap(self: #original_type_name) -> #ok_type; },
539                        )?;
540                    let unwrap_unchecked_extern_function = create_extern_function_for_custom_type(
541                        wrapper_name,
542                        &unwrap_unchecked_function,
543                    );
544                    let (_, unwrap_err_unchecked_function) = local_extern_mod_translator
545                        .translate_function(
546                            &parse_quote! { fn unwrap_err_unchecked(self: #original_type_name) -> #exc_type; },
547                        )?;
548                    let unwrap_err_unchecked_extern_function = create_extern_function_for_custom_type(
549                        wrapper_name,
550                        &unwrap_err_unchecked_function,
551                    );
552                    Ok(vec![
553                        from_ok_extern_function,
554                        from_err_extern_function,
555                        is_ok_extern_function,
556                        unwrap_unchecked_extern_function,
557                        unwrap_err_unchecked_extern_function,
558                    ])
559                },
560                _ => Ok(vec![])
561            })
562            .collect::<anyhow::Result<Vec<_>>>()?
563            .into_iter()
564            .flatten()
565            .for_each(|f| self.register_extern_function(f));
566        Ok(())
567    }
568
569    fn create_option_extern_functions(
570        wrapper: &WrapperType,
571        inner_type: &WrapperType,
572        original_type_name: &Type,
573        wrapper_name: &str,
574        local_extern_mod_translator: &mut ExternModuleTranslator,
575    ) -> anyhow::Result<Vec<ExternFunction>> {
576        let inner_type = &inner_type.original_type_name;
577
578        let (_, new_function) = local_extern_mod_translator.translate_function(
579            &parse_quote! { fn from(val: #inner_type) -> #original_type_name; },
580        )?;
581        let wrapper_without_generics = WrapperType {
582            original_type_name: syn::parse_str("Option").unwrap(),
583            ..wrapper.clone()
584        };
585        let from_extern_function = create_extern_associated_function_for_custom_type(
586            wrapper_without_generics,
587            &new_function,
588        );
589        let (_, new_function) = local_extern_mod_translator
590            .translate_function(&parse_quote! { fn default() -> #original_type_name; })?;
591        let wrapper_without_generics = WrapperType {
592            original_type_name: syn::parse_str("Option").unwrap(),
593            ..wrapper.clone()
594        };
595        let default_extern_function = create_extern_associated_function_for_custom_type(
596            wrapper_without_generics,
597            &new_function,
598        );
599
600        let (_, is_some_function) = local_extern_mod_translator.translate_function(
601            &parse_quote! { fn is_some(self: &#original_type_name) -> bool; },
602        )?;
603        let is_ok_extern_function =
604            create_extern_function_for_custom_type(wrapper_name, &is_some_function);
605        let (_, unwrap_unchecked_function) = local_extern_mod_translator.translate_function(
606            &parse_quote! { fn unwrap(self: #original_type_name) -> #inner_type; },
607        )?;
608        let unwrap_unchecked_extern_function =
609            create_extern_function_for_custom_type(wrapper_name, &unwrap_unchecked_function);
610        Ok(vec![
611            from_extern_function,
612            default_extern_function,
613            is_ok_extern_function,
614            unwrap_unchecked_extern_function,
615        ])
616    }
617
618    fn create_vector_extern_functions(
619        wrapper: &WrapperType,
620        inner_type: &WrapperType,
621        original_type_name: &Type,
622        wrapper_name: &str,
623        local_extern_mod_translator: &mut ExternModuleTranslator,
624    ) -> anyhow::Result<Vec<ExternFunction>> {
625        let inner_type_original = &inner_type.original_type_name;
626
627        let (_, new_function) = local_extern_mod_translator
628            .translate_function(&parse_quote! { fn new() -> #original_type_name; })?;
629        let wrapper_without_generics = WrapperType {
630            original_type_name: syn::parse_str("Vec").unwrap(),
631            ..wrapper.clone()
632        };
633        let new_extern_function = create_extern_associated_function_for_custom_type(
634            wrapper_without_generics,
635            &new_function,
636        );
637
638        let (_, with_capacity_function) = local_extern_mod_translator.translate_function(
639            &parse_quote! { fn with_capacity(capacity: usize) -> #original_type_name; },
640        )?;
641        let wrapper_without_generics = WrapperType {
642            original_type_name: syn::parse_str("Vec").unwrap(),
643            ..wrapper.clone()
644        };
645        let with_capacity_extern_function = create_extern_associated_function_for_custom_type(
646            wrapper_without_generics,
647            &with_capacity_function,
648        );
649
650        let get_extern_function =
651            create_get_from_vec_extern_function(wrapper.clone(), inner_type.clone());
652
653        let (_, push_function) = local_extern_mod_translator.translate_function(
654            &parse_quote! { fn push(self: &#original_type_name, obj: #inner_type_original); },
655        )?;
656        let push_extern_function =
657            create_extern_function_for_custom_type(wrapper_name, &push_function);
658
659        let (_, as_mut_ptr_function) = local_extern_mod_translator
660            .translate_function(&parse_quote! { fn as_mut_ptr(self: &#original_type_name) -> *mut #inner_type_original; })?;
661        let as_mut_ptr_extern_function =
662            create_extern_function_for_custom_type(wrapper_name, &as_mut_ptr_function);
663
664        let (_, len_function) = local_extern_mod_translator
665            .translate_function(&parse_quote! { fn len(self: &#original_type_name) -> usize; })?;
666        let len_extern_function =
667            create_extern_function_for_custom_type(wrapper_name, &len_function);
668
669        let (_, set_len_function) = local_extern_mod_translator.translate_function(
670            &parse_quote! { fn set_len(self: &#original_type_name, new_len: usize); },
671        )?;
672        let set_len_extern_function =
673            create_extern_function_for_custom_type(wrapper_name, &set_len_function);
674        Ok(vec![
675            new_extern_function,
676            with_capacity_extern_function,
677            get_extern_function,
678            push_extern_function,
679            len_extern_function,
680            set_len_extern_function,
681            as_mut_ptr_extern_function,
682        ])
683    }
684
685    fn create_wrappers_for_builtins(&mut self) -> anyhow::Result<()> {
686        self.extern_module_translator
687            .rust_types_wrappers
688            .clone()
689            .unordered_iter()
690            .map(|wrapper| match wrapper {
691                WrapperType {
692                    original_type_name,
693                    wrapper_name,
694                    rust_type: RustWrapperType::Option(inner_type),
695                    ..
696                } => BindingModule::create_option_extern_functions(
697                    wrapper,
698                    inner_type,
699                    original_type_name,
700                    wrapper_name,
701                    &mut self.extern_module_translator,
702                ),
703                WrapperType {
704                    original_type_name,
705                    wrapper_name,
706                    rust_type: RustWrapperType::Vector(inner_type),
707                    ..
708                } => BindingModule::create_vector_extern_functions(
709                    wrapper,
710                    inner_type,
711                    original_type_name,
712                    wrapper_name,
713                    &mut self.extern_module_translator,
714                ),
715                _ => Ok(vec![]),
716            })
717            .collect::<anyhow::Result<Vec<_>>>()?
718            .into_iter()
719            .flatten()
720            .for_each(|f| self.register_extern_function(f));
721        Ok(())
722    }
723
724    /// Generates impl blocks for each custom user's Rust trait exposed via FFI
725    ///
726    fn create_wrappers_for_traits(&mut self) {
727        let drop_native_ref: TokenStream = quote! {
728            extern "C" {
729                #[link_name = #DROP_FUNCTION_SYMBOL_NAME]
730                fn drop_native_ref(input: *mut std::ffi::c_void);
731            }
732        };
733        self.wrappers_impls.extend(drop_native_ref);
734
735        let limit_lifetime: TokenStream = quote! {
736            fn limit_lifetime<'a, T: ?Sized>(r: &'static T, _: &'a ()) -> &'a T {
737                r
738            }
739        };
740        self.wrappers_impls.extend(limit_lifetime);
741
742        let limit_lifetime_mut: TokenStream = quote! {
743            fn limit_lifetime_mut<'a, T: ?Sized>(r: &'static mut T, _: &'a mut ()) -> &'a mut T {
744                r
745            }
746        };
747        self.wrappers_impls.extend(limit_lifetime_mut);
748
749        for (custom_type, functions) in &self.extern_module_translator.user_traits {
750            if custom_type.rust_type == RustWrapperType::Trait {
751                let wrapper_name = Ident::new(&custom_type.wrapper_name, Span::call_site());
752                let generated_functions =
753                    generate_trait_methods(functions.iter(), &custom_type.wrapper_name);
754                let generated_wrapper_impl: TokenStream = quote! {
755                    pub struct #wrapper_name(std::sync::atomic::AtomicPtr<std::ffi::c_void>);
756                    impl super::#wrapper_name for #wrapper_name {
757                        #(#generated_functions)*
758                    }
759
760                    impl #wrapper_name {
761                        fn new(inner: *mut std::ffi::c_void) -> Self {
762                            Self(std::sync::atomic::AtomicPtr::new(inner))
763                        }
764                    }
765
766                    impl Drop for #wrapper_name {
767                        fn drop(&mut self) {
768                            unsafe { drop_native_ref(self.0.load(std::sync::atomic::Ordering::Relaxed)) }
769                        }
770                    }
771                };
772                self.wrappers_impls.extend(generated_wrapper_impl);
773                let extern_link_functions = functions.iter().map(|function| {
774                    let function_name = &function.name;
775                    let export_function_name =
776                        format!("{EXPORTED_SYMBOLS_PREFIX}${wrapper_name}${function_name}");
777                    let function_name = Ident::new(
778                        &format!("{EXPORTED_SYMBOLS_PREFIX}{wrapper_name}_{function_name}"),
779                        Span::call_site(),
780                    );
781                    let return_type = match &function.return_type {
782                        Some(WrapperType {
783                            original_type_name,
784                            rust_type: RustWrapperType::Primitive | RustWrapperType::FieldlessEnum,
785                            ..
786                        }) => original_type_name.clone(),
787                        Some(WrapperType {
788                            original_type_name, ..
789                        }) => parse_quote! { *mut #original_type_name },
790                        _ => parse_quote! { () },
791                    };
792                    let mut args = prepare_extern_function_signature(function);
793                    if let Some(self_arg) = args.first_mut() {
794                        *self_arg = parse_quote! {_self: *mut std::ffi::c_void}
795                    }
796                    quote! {
797                        extern "C" {
798                            #[link_name = #export_function_name]
799                            fn #function_name(#args) -> #return_type;
800                        }
801                    }
802                });
803                self.wrappers_impls.extend(extern_link_functions);
804            }
805        }
806    }
807
808    fn create_wrappers_for_exception_trait(&mut self) {
809        let exception_types_names_iter = self
810            .extern_module_translator
811            .rust_types_wrappers
812            .unordered_iter()
813            .filter_map(|wrapper| {
814                if matches!(wrapper.rust_type, RustWrapperType::Exceptions(_)) {
815                    Some(wrapper.wrapper_name.clone())
816                } else {
817                    None
818                }
819            })
820            .collect::<Vec<String>>();
821
822        self.extern_module_translator
823            .exception_trait_methods
824            .iter()
825            .flat_map(|function| {
826                exception_types_names_iter
827                    .clone()
828                    .iter()
829                    .map(|wrapper_name| {
830                        create_extern_function_for_exception_trait_method(wrapper_name, function)
831                    })
832                    .collect::<Vec<_>>()
833            })
834            .collect::<Vec<_>>()
835            .into_iter()
836            .for_each(|f| self.register_extern_function(f));
837    }
838
839    fn create_wrappers_for_global_functions(&mut self) {
840        self.extern_module_translator
841            .global_functions
842            .iter()
843            .map(create_extern_global_function)
844            .collect::<Vec<_>>()
845            .into_iter()
846            .for_each(|f| self.register_extern_function(f));
847    }
848
849    fn create_wrappers_for_strings(&mut self) -> anyhow::Result<()> {
850        let wrapper = WrapperType {
851            original_type_name: syn::parse_str("String").unwrap(),
852            wrapper_name: "RustString".to_owned(),
853            rust_type: RustWrapperType::String,
854            reference_parameters: Some(ReferenceParameters::shared()),
855            impl_traits: vec![],
856        };
857        let original_type_name = &wrapper.original_type_name;
858        let wrapper_name = &wrapper.wrapper_name;
859
860        let (_, new_function) = self
861            .extern_module_translator
862            .translate_function(&parse_quote! { fn new() -> #original_type_name; })?;
863        let new_extern_function =
864            create_extern_associated_function_for_custom_type(wrapper.clone(), &new_function);
865
866        let from_c_str_extern_function = create_from_c_str_extern_function(wrapper.clone());
867
868        let (_, as_mut_ptr_function) = self.extern_module_translator.translate_function(
869            &parse_quote! { fn as_mut_ptr(self: &#original_type_name) -> &mut u8; },
870        )?;
871        let as_mut_ptr_extern_function =
872            create_extern_function_for_custom_type(wrapper_name, &as_mut_ptr_function);
873
874        let (_, len_function) = self
875            .extern_module_translator
876            .translate_function(&parse_quote! { fn len(self: &#original_type_name) -> usize; })?;
877        let len_extern_function =
878            create_extern_function_for_custom_type(wrapper_name, &len_function);
879
880        let clone_extern_function = create_clone_extern_function(wrapper.clone());
881
882        let drop_extern_function = create_drop_extern_function(wrapper.clone());
883
884        [
885            new_extern_function,
886            from_c_str_extern_function,
887            as_mut_ptr_extern_function,
888            len_extern_function,
889            clone_extern_function,
890            drop_extern_function,
891        ]
892        .into_iter()
893        .for_each(|f| self.register_extern_function(f));
894        Ok(())
895    }
896
897    fn create_wrappers_for_clones(&mut self) {
898        self.extern_module_translator
899            .rust_types_wrappers
900            .unordered_iter()
901            .flat_map(|wrapper| match wrapper.rust_type {
902                RustWrapperType::Trait
903                | RustWrapperType::String
904                | RustWrapperType::Primitive
905                | RustWrapperType::FieldlessEnum
906                | RustWrapperType::ExceptionTrait
907                | RustWrapperType::Exceptions(_) => vec![],
908                _ => vec![
909                    create_clone_extern_function(wrapper.clone()),
910                    create_drop_extern_function(wrapper.clone()),
911                ],
912            })
913            .collect::<Vec<_>>()
914            .into_iter()
915            .for_each(|f| self.register_extern_function(f));
916    }
917}