pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub mod cli;
pub mod compare;
pub mod config;
pub mod departures;
pub mod document_refusals;
pub mod emit;
pub mod error;
pub mod ir;
mod name_refusals;
pub mod naming;
pub mod normalize;
pub mod openapi;
pub mod parity;
pub mod pyfmt;
pub mod refs;
pub mod schema;
pub mod settings;
pub mod wrap;
mod yaml;
pub use emit::GeneratedFile;
pub use error::{Error, Result};
pub use normalize::strip_python_comments;
use std::path::PathBuf;
use config::GenerateConfig;
#[derive(Debug, Clone)]
pub struct GenerateArgs {
pub spec: PathBuf,
pub output: PathBuf,
pub package_name: Option<String>,
pub project_name: Option<String>,
pub client_class_name: Option<String>,
pub audiences: Vec<String>,
pub audience_strict: bool,
pub extra_fields: settings::ExtraFields,
pub enum_type: settings::EnumType,
pub default_max_retries: u32,
pub fern_strict: bool,
pub layout: settings::Layout,
}
pub fn generate(args: GenerateArgs) -> Result<Vec<GeneratedFile>> {
document_refusals::check_version_file(&args.spec, args.fern_strict)?;
document_refusals::check_structure_file(&args.spec, args.fern_strict)?;
let mut doc = name_refusals::load(&args)?;
openapi::filter_ignored(&mut doc);
openapi::filter_by_audience(&mut doc, &args.audiences, args.audience_strict);
document_refusals::check(&doc, &args.spec, args.fern_strict)?;
let mut config = GenerateConfig::new(
args.spec.clone(),
args.output.clone(),
args.package_name,
args.project_name,
args.client_class_name,
args.extra_fields,
&doc.info.title,
)?;
config.layout = args.layout;
config.enum_type = args.enum_type;
config.default_max_retries = args.default_max_retries;
let ir = ir::build(&doc, &config);
if let Some(message) = ir.unemittable_extension() {
return Err(Error::InvalidSpec {
path: args.spec.clone(),
message,
});
}
document_refusals::check_sdk(&mut doc, &ir, &config, &args.spec, args.fern_strict)?;
name_refusals::validate(&doc, &args.spec, args.fern_strict, &ir)?;
name_refusals::validate_ir(&ir, &doc, &args.spec, args.fern_strict)?;
let files = emit::generate(&ir)?;
match config.layout {
settings::Layout::Packaged => {
emit::clean_package_tree(&config.output, config.package_name.as_str())?;
}
settings::Layout::Flat => emit::clean_flat_tree(&config.output)?,
}
emit::write_files(&config.output, &files)?;
Ok(files)
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResolvedNames {
pub package_name: String,
pub project_name: String,
pub client_class_name: String,
}
pub fn resolved_names(args: &GenerateArgs) -> Result<ResolvedNames> {
let doc = openapi::load(&args.spec)?;
let config = GenerateConfig::new(
args.spec.clone(),
args.output.clone(),
args.package_name.clone(),
args.project_name.clone(),
args.client_class_name.clone(),
args.extra_fields,
&doc.info.title,
)?;
let client_class_name = config
.client_class_name
.clone()
.unwrap_or_else(|| config::default_client_class_name(config.package_name.as_str()));
Ok(ResolvedNames {
package_name: config.package_name.as_str().to_string(),
project_name: config.project_name,
client_class_name,
})
}
pub fn render_files(args: GenerateArgs) -> Result<Vec<GeneratedFile>> {
document_refusals::check_version_file(&args.spec, args.fern_strict)?;
document_refusals::check_structure_file(&args.spec, args.fern_strict)?;
let mut doc = name_refusals::load(&args)?;
openapi::filter_ignored(&mut doc);
openapi::filter_by_audience(&mut doc, &args.audiences, args.audience_strict);
document_refusals::check(&doc, &args.spec, args.fern_strict)?;
let mut config = GenerateConfig::new(
args.spec.clone(),
args.output.clone(),
args.package_name,
args.project_name,
args.client_class_name,
args.extra_fields,
&doc.info.title,
)?;
config.layout = args.layout;
config.enum_type = args.enum_type;
config.default_max_retries = args.default_max_retries;
let ir = ir::build(&doc, &config);
if let Some(message) = ir.unemittable_extension() {
return Err(Error::InvalidSpec {
path: args.spec.clone(),
message,
});
}
document_refusals::check_sdk(&mut doc, &ir, &config, &args.spec, args.fern_strict)?;
name_refusals::validate(&doc, &args.spec, args.fern_strict, &ir)?;
name_refusals::validate_ir(&ir, &doc, &args.spec, args.fern_strict)?;
emit::generate(&ir)
}