#![doc = include_str!("../Readme.md")]
use file_parser::parse_schemas;
use generated_schema::namespace::NamespaceInfo;
use std::{path::PathBuf, str::FromStr};
use crate::error::Result;
use clap::Parser;
use clap_verbosity::Verbosity;
use log::{debug, info, LevelFilter};
mod browse_sub_schemas;
mod error;
mod file_parser;
mod generated_schema;
mod source;
mod writers;
#[cfg( feature = "schema_registry")]
mod schema_registry;
#[derive(Debug, Parser)]
#[command(version)]
pub struct Avrogen {
#[clap(skip)]
#[cfg( feature = "schema_registry")]
schema_registry_source: Option<crate::schema_registry::SchemaRegistrySource>,
#[arg(short='s', long, num_args=..)]
source: Vec<String>,
#[arg(short='n', long, aliases=&["namespace", "default_namespace", "default-namespace"])]
default_namespace: Option<String>,
#[arg(long, short='o', default_value="./", aliases=&["output-folder","outputfolder"])]
output_folder: PathBuf,
#[command(flatten)]
verbose: Verbosity,
log_level: Option<LevelFilter>,
#[arg(long)]
flat_ouptut: bool
}
impl Default for Avrogen {
fn default() -> Self {
Avrogen::new()
}
}
impl Avrogen {
pub fn new() -> Self {
Avrogen {
source: vec![],
default_namespace: None,
output_folder: PathBuf::from("./"),
verbose: Verbosity::default(),
log_level: None,
flat_ouptut: false,
#[cfg( feature = "schema_registry")]
schema_registry_source: None,
}
}
pub fn add_sources(mut self, mut file_patterns: Vec<String>) -> Self {
self.source.append(&mut file_patterns);
self
}
pub fn add_source(mut self, file_pattern: &str) -> Self {
self.source.push(file_pattern.to_string());
self
}
#[cfg( feature = "schema_registry")]
pub fn add_schema_registry_source(mut self, schema_registry_source: &str,local_folder: &str) -> Self {
self.schema_registry_source= Some(crate::schema_registry::SchemaRegistrySource::new(schema_registry_source.to_string(),local_folder.to_string()));
self
}
#[cfg( feature = "schema_registry")]
pub fn add_subject(mut self, subject: &str) -> Self {
if let Some(schema_registry_source) = self.schema_registry_source.as_mut() {
schema_registry_source.add_subject(subject);
}
else {
log::error!("add_schema_registry_source must be called first!");
}
self
}
pub fn default_namespace(mut self, default_namespace: &str) -> Self {
self.default_namespace = Some(default_namespace.to_string());
self
}
pub fn output_folder(mut self, output_folder: PathBuf) -> Self {
self.output_folder = output_folder;
self
}
pub fn output_folder_from_str(mut self, output_folder: &str) -> Self {
self.output_folder = PathBuf::from_str(output_folder).unwrap();
self
}
pub fn set_verbosity_off(mut self) -> Self {
self.log_level = Some(LevelFilter::Off);
self
}
pub fn set_verbosity_debug(mut self) -> Self {
self.log_level = Some(LevelFilter::Debug);
self
}
pub fn set_flat_output(mut self) -> Self {
self.flat_ouptut= true;
self
}
pub fn set_verbosity_info(mut self) -> Self {
self.log_level = Some(LevelFilter::Info);
self
}
pub fn set_verbosity_warn(mut self) -> Self {
self.log_level = Some(LevelFilter::Warn);
self
}
pub fn set_verbosity_error(mut self) -> Self {
self.log_level = Some(LevelFilter::Error);
self
}
pub fn verbosity(mut self, level_filter: log::LevelFilter) -> Self {
self.log_level = Some(level_filter);
self
}
fn log_level(&self) -> LevelFilter {
if let Some(x) = self.log_level {
return x;
}
self.verbose.log_level_filter()
}
pub fn execute(self) -> Result<()> {
let mut builder = colog::basic_builder();
builder.filter(None, self.log_level());
let _ = builder.try_init();
info!("1) Browse source to get content");
#[allow(unused_mut)]
let mut file_contents = source::read_files(self.source)?;
#[cfg( feature = "schema_registry")]
if let Some(schema_registry_source) = self.schema_registry_source {
info!("1.bis) Browse schema registry source");
let schemas = schema_registry_source.get_schemas()?;
file_contents.extend( schemas );
}
info!("2) Parsing file to get schemas...");
let root_schemas = parse_schemas(file_contents)?;
let mut root_ns = NamespaceInfo::root(self.default_namespace);
debug!(
"{} root schemas found, browse sub schemas...",
root_schemas.len()
);
let root_schemas = root_schemas.iter().collect();
let all_schemas = browse_sub_schemas::all_schemas_to_generate(root_schemas);
debug!("Total of {} schemas found", all_schemas.len());
info!("3) Process schemas to get informations...");
for schema in all_schemas {
root_ns.process_schema(schema)?;
}
info!("4) Write to files");
writers::write(self.output_folder, root_ns, self.flat_ouptut)?;
info!("Done!");
Ok(())
}
}