1use 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;
40use 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#[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
84pub struct BindingModule {
89 extern_module_translator: ExternModuleTranslator,
90 wrappers_impls: TokenStream,
91 extern_functions: Vec<ExternFunction>,
92}
93
94impl BindingModule {
95 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 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 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 pub fn get_tokens(&self) -> TokenStream {
169 self.wrappers_impls.clone()
170 }
171
172 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 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 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}