1#![allow(missing_docs)]
20#![allow(
21 clippy::collapsible_else_if,
22 clippy::if_same_then_else,
23 clippy::match_like_matches_macro,
24 clippy::only_used_in_recursion
25)]
26
27pub mod adapters;
28pub mod backends;
29pub mod bin_cli;
30pub mod cli;
31pub mod codegen;
32pub mod component;
33pub mod core;
34pub mod docs;
35pub mod e2e;
36pub mod extensions;
37pub mod extract;
38pub(crate) mod process;
39pub mod publish;
40pub mod readme;
41pub mod scaffold;
42pub mod snippets;
43pub mod template;
44#[cfg(test)]
45pub(crate) mod test_support;
46
47pub use core::extension::{Extension, ExtensionConfig};
48pub use core::template_env::TemplateEnv;
49pub use extensions::template::TemplateExtension;
50
51pub use core::backend::GeneratedFile;
52pub use core::config::{E2eConfig, Language, ResolvedCrateConfig};
53pub use core::ir::{ApiSurface, EnumDef, TypeDef};
54pub use e2e::fixture::{Fixture, FixtureGroup, group_fixtures, load_fixtures};
55
56pub fn run_with_extensions(mut extensions: Vec<Box<dyn Extension>>) -> std::process::ExitCode {
69 use clap::Parser;
70
71 extensions.insert(0, Box::new(TemplateExtension));
72
73 let cli = bin_cli::args::Cli::parse();
74 bin_cli::helpers::init_tracing(cli.verbose, cli.quiet, cli.no_color);
75
76 if cli.jobs > 0 {
77 rayon::ThreadPoolBuilder::new()
78 .num_threads(cli.jobs)
79 .build_global()
80 .ok();
81 }
82
83 #[cfg(feature = "dylib-loader")]
84 match extensions::dylib::load_dylib_extensions_from_config(&cli.config) {
85 Ok(mut dylib_extensions) => extensions.append(&mut dylib_extensions),
86 Err(e) => {
87 tracing::error!("{e:#}");
88 return std::process::ExitCode::FAILURE;
89 }
90 }
91
92 let _ = EXTENSIONS.set(extensions);
93
94 match bin_cli::dispatch::run(cli) {
95 Ok(()) => std::process::ExitCode::SUCCESS,
96 Err(e) => {
97 tracing::error!("{e:#}");
98 std::process::ExitCode::FAILURE
99 }
100 }
101}
102
103pub(crate) static EXTENSIONS: std::sync::OnceLock<Vec<Box<dyn Extension>>> = std::sync::OnceLock::new();
109
110pub(crate) fn with_extensions<F, R>(f: F) -> R
112where
113 F: FnOnce(&[Box<dyn Extension>]) -> R,
114{
115 static EMPTY: Vec<Box<dyn Extension>> = Vec::new();
116 f(EXTENSIONS.get().unwrap_or(&EMPTY))
117}