ferment_sys/
builder.rs

1use crate::{Config, Crate, error, Lang};
2#[cfg(not(feature = "cbindgen_only"))]
3use crate::ast::Depunctuated;
4#[cfg(not(feature = "cbindgen_only"))]
5use crate::tree::FileTreeProcessor;
6use crate::tree::Writer;
7use crate::lang::rust::find_crates_paths;
8#[cfg(not(feature = "cbindgen_only"))]
9use crate::presentation::{Fermentate, RustFermentate};
10
11extern crate env_logger;
12
13#[derive(Debug, Clone)]
14pub struct Builder {
15    config: Config,
16}
17
18impl Builder {
19    pub fn new(current_crate: Crate) -> Builder {
20        env_logger::init();
21        Builder { config: Config::new("fermented", current_crate, cbindgen::Config::default()) }
22        // Builder { config: Config::new("fermented", current_crate, "cbindgen.toml") }
23    }
24    #[allow(unused)]
25    pub fn with_crate_name(crate_name: &str) -> Builder {
26        Self::new(Crate::current_with_name(crate_name))
27    }
28
29    #[allow(unused)]
30    pub fn with_default_mod_name(mut self) -> Builder {
31        self.config.mod_name = String::from("fermented");
32        self
33    }
34    #[allow(unused)]
35    pub fn with_cbindgen_config(mut self, config: cbindgen::Config) -> Builder {
36        self.config.cbindgen_config = config;
37        self
38    }
39    #[allow(unused)]
40    pub fn with_cbindgen_config_from_file(mut self, config: &'static str) -> Builder {
41        self.config.cbindgen_config_from_file = Some(config.to_string());
42        self
43    }
44    #[allow(unused)]
45    pub fn with_mod_name<S: AsRef<str>>(mut self, mod_name: S) -> Builder {
46        self.config.mod_name = String::from(mod_name.as_ref());
47        self
48    }
49
50    #[allow(unused)]
51    pub fn with_crates(mut self, crates: Vec<&str>) -> Builder {
52        self.config.external_crates = find_crates_paths(crates);
53        self
54    }
55    #[allow(unused)]
56    pub fn with_external_crates(mut self, crates: Vec<&str>) -> Builder {
57        self.config.external_crates = find_crates_paths(crates);
58        self
59    }
60
61    #[allow(unused)]
62    pub fn with_languages(mut self, languages: Vec<Lang>) -> Builder {
63        self.config.languages = languages;
64        self
65    }
66
67    /// Reads rust file and its nested dependencies
68    /// Creates syntax tree which we'll use later
69    /// to handle imports for FFI converted types
70    /// `mod_name`: mod with this name will be created in `src/{mod_name}.rs`
71    ///
72    /// Recursively reads a Rust project file tree and its nested dependencies to generate a syntax tree.
73    ///
74    /// This function will traverse the primary Rust file and its dependencies to generate
75    /// a syntax tree. This tree is later utilized to manage imports for types that are
76    /// converted for FFI.
77    ///
78    /// The resulting code will be written into a new module file in the `src/` directory.
79    ///
80    /// # Arguments
81    ///
82    /// * `mod_name`: The name of the module to be created. The resulting file will be
83    ///   named `{mod_name}.rs` and will be located inside the `src/` directory.
84    ///
85    /// # Errors
86    ///
87    /// If the function encounters any errors while reading the file, processing the syntax,
88    /// or writing to the output file, it will return an `error::Error`.
89    ///
90    /// # Example
91    ///
92    /// ```no_run
93    /// # extern crate ferment_sys;
94    /// use ferment_sys::{Crate, Ferment, Lang};
95    /// let mut languages = vec![];
96    /// #[cfg(feature = "objc")]
97    /// languages.push(Lang::ObjC(ferment::ObjC::new("DS", "Fermented")));
98    /// #[cfg(feature = "java")]
99    /// languages.push(Lang::Java(ferment::Java::new("Fermented")));
100    /// Ferment::with_crate_name("your_crate_name")
101    ///     .with_default_mod_name()
102    ///     .with_crates(vec![])
103    ///     .with_languages(languages)
104    ///     .generate()
105    ///     .expect("Fermentation fault");
106    /// ```
107    ///
108    /// # Remarks
109    ///
110    /// This function expects the primary Rust file to be named `lib.rs` and located inside
111    /// the `src/` directory. Any deviation from this naming and structure might lead to errors.
112    ///
113    /// The resulting module will only contain the necessary imports and types suitable for FFI conversion.
114    ///
115    pub fn generate(self) -> Result<(), error::Error> {
116        #[cfg(not(feature = "cbindgen_only"))]
117        let fermentate = {
118            let crate_tree = FileTreeProcessor::build(&self.config)?;
119            Depunctuated::from_iter([
120                Fermentate::Rust(RustFermentate::CrateTree(crate_tree.clone())),
121                #[cfg(feature = "objc")]
122                Fermentate::ObjC(crate::lang::objc::ObjCFermentate::CrateTree(crate_tree))
123            ])
124        };
125        let writer = Writer::from(self.config);
126        #[cfg(not(feature = "cbindgen_only"))]
127        writer.write(fermentate)?;
128        writer.write_headers()
129    }
130}
131