Skip to main content

satay_codegen/
lib.rs

1#![forbid(unsafe_code)]
2#![allow(
3    clippy::cast_possible_truncation,
4    clippy::doc_markdown,
5    clippy::elidable_lifetime_names,
6    clippy::float_cmp,
7    clippy::if_not_else,
8    clippy::map_unwrap_or,
9    clippy::match_same_arms,
10    clippy::needless_pass_by_value,
11    clippy::ref_option,
12    clippy::redundant_closure_for_method_calls,
13    clippy::single_match_else,
14    clippy::struct_field_names,
15    clippy::trivially_copy_pass_by_ref,
16    clippy::unnecessary_wraps
17)]
18
19mod error;
20mod ident;
21mod model;
22mod parse;
23mod render;
24
25pub use error::{Error, ParseError, ValidationError};
26pub use render::GeneratedFile;
27use tracing::info;
28
29/// Which root module file to emit at the output directory root.
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
31pub enum RootModule {
32    /// `mod.rs` (default).
33    #[default]
34    ModRs,
35    /// `lib.rs` for a generated crate root.
36    LibRs,
37}
38
39/// Options for code generation.
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
41pub struct GenerateOptions {
42    /// Root module filename (`mod.rs` or `lib.rs`).
43    pub root_module: RootModule,
44}
45
46/// Generates Rust files from an OpenAPI specification.
47///
48/// # Errors
49///
50/// Returns an error if the specification cannot be parsed, validated, or rendered.
51#[tracing::instrument(err)]
52pub fn generate(spec: &str) -> Result<Vec<GeneratedFile>, Error> {
53    generate_with(spec, GenerateOptions::default())
54}
55
56/// Generates Rust files from an OpenAPI specification with explicit options.
57///
58/// # Errors
59///
60/// Returns an error if the specification cannot be parsed, validated, or rendered.
61#[tracing::instrument(err)]
62pub fn generate_with(spec: &str, options: GenerateOptions) -> Result<Vec<GeneratedFile>, Error> {
63    info!("parsing OpenAPI document");
64    let document = parse::parse_document(spec)?;
65    let api = parse::parse_api(&document)?;
66    info!(
67        components = api.components.len(),
68        operations = api.operations.len(),
69        "parsed API"
70    );
71    Ok(render::render_api(&api, options))
72}