rsbind_core/swift/
mod.rs

1use crate::ast::types::AstType;
2use crate::base::bridge::{BaseBridgeGen, FilesGenerator};
3use crate::base::lang::{LangGen, LangImp, ModContext};
4use crate::errors::*;
5use crate::swift::artifact::SwiftCodeGen;
6use crate::{ident, AstResult};
7use bridge::SwiftImp;
8use rstgen::swift::Swift;
9use std::path::Path;
10mod artifact;
11mod bridge;
12mod callback;
13mod converter;
14mod internal;
15mod manager;
16mod protocol;
17mod struct_;
18mod ty;
19mod types;
20mod wrapper;
21
22pub(crate) struct SwiftGen {
23    pub(crate) crate_name: String,
24    pub(crate) ast: AstResult,
25}
26
27impl LangGen for SwiftGen {
28    fn gen_bridge(&self, path: &Path) -> Result<()> {
29        let mut generator = FilesGenerator::<Swift<'static>, ()>::default();
30        let old_arg_convert = generator
31            .bridge_file_generator
32            .bridge_code_generator
33            .trait_generator
34            .trait_method_generator
35            .quote_method_return_convert;
36
37        // We overwrite the base return-convert method because of the deadlock problem.
38        // If we read and write lock in converting method will result deadlock.
39        generator
40            .bridge_file_generator
41            .bridge_code_generator
42            .trait_generator
43            .trait_method_generator
44            .quote_method_return_convert = Box::new(move |ctx| {
45            let obtain_index = if let AstType::Callback(_) = ctx.method.return_type.clone() {
46                quote! {
47                    let callback_index = {
48                        let mut global_index = CALLBACK_INDEX.write().unwrap();
49                        let mut index = *global_index;
50                        if index == i64::MAX {
51                            *global_index = 0;
52                            index = 0;
53                        } else {
54                            *global_index = index + 1;
55                            index = index + 1;
56                        }
57                        index
58                    };
59                }
60            } else {
61                quote! {}
62            };
63
64            let convert = (*old_arg_convert)(ctx)?;
65            let return_convert = quote! {
66                let r_result = #convert;
67            };
68
69            let insert_callback = if let AstType::Callback(ref origin) =
70                ctx.method.return_type.clone()
71            {
72                let callback_ident = ident!(&origin.origin);
73                quote! {
74                    (*CALLBACK_HASHMAP.write().unwrap()).insert(callback_index, CallbackEnum::#callback_ident(result));
75                }
76            } else {
77                quote! {}
78            };
79
80            Ok(quote! {
81                #obtain_index
82                #return_convert
83                #insert_callback
84                r_result
85            })
86        });
87
88        BaseBridgeGen {
89            lang_name: "swift".to_string(),
90            ast: &self.ast,
91            bridge_dir: path,
92            crate_name: self.crate_name.clone(),
93            lang_imp: Box::new(SwiftImp {}),
94            extra: (),
95            generator,
96        }
97        .gen()
98    }
99
100    fn gen_native(&self, path: &Path) -> Result<()> {
101        SwiftCodeGen {
102            swift_gen_dir: &path.to_path_buf(),
103            ast: &self.ast,
104        }
105        .gen_files()
106    }
107}