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