use std::{env, fs, path::Path};
use rsgen_avro::{FieldOverride, GeneratorBuilder, ImplementAvroSchema, Result, Source};
#[cfg(feature = "macro")]
pub use avrogant_macro::include_schema;
pub struct AvroCompiler {
generator: GeneratorBuilder,
}
impl Default for AvroCompiler {
fn default() -> Self {
Self {
generator: GeneratorBuilder::new(),
}
}
}
impl AvroCompiler {
pub fn new() -> Self {
Self::default()
}
pub fn precision(mut self, precision: usize) -> Self {
self.generator = self.generator.precision(precision);
self
}
pub fn nullable(mut self, nullable: bool) -> Self {
self.generator = self.generator.nullable(nullable);
self
}
pub fn use_avro_rs_unions(mut self, use_avro_rs_unions: bool) -> Self {
self.generator = self.generator.use_avro_rs_unions(use_avro_rs_unions);
self
}
pub fn use_chrono_dates(mut self, use_chrono_dates: bool) -> Self {
self.generator = self.generator.use_chrono_dates(use_chrono_dates);
self
}
pub fn derive_builders(mut self, derive_builders: bool) -> Self {
self.generator = self.generator.derive_builders(derive_builders);
self
}
pub fn implement_avro_schema(mut self, impl_schemas: ImplementAvroSchema) -> Self {
self.generator = self.generator.implement_avro_schema(impl_schemas);
self
}
pub fn extra_derives(mut self, extra_derives: Vec<String>) -> Self {
self.generator = self.generator.extra_derives(extra_derives);
self
}
pub fn override_fields(mut self, overrides: Vec<FieldOverride>) -> Self {
self.generator = self.generator.override_fields(overrides);
self
}
pub fn override_field(mut self, over: FieldOverride) -> Self {
self.generator = self.generator.override_field(over);
self
}
pub fn compile(self, schemas: &[impl AsRef<Path>]) -> Result<()> {
let generator = self.generator.build()?;
for schema in schemas {
let mut buf = vec![];
let path = schema.as_ref();
let schema = path
.to_str()
.expect("Schema path is not a valid UTF-8 string");
let file_name = path.file_prefix().expect("Invalid schema path, ensure it has a file name with it's extension (e.g.: foo_*_bar.avsc)");
let output_dir =
env::var_os("OUT_DIR").expect("OUT_DIR environment variable is not present");
let path = Path::new(&output_dir).join(format!("{}.rs", file_name.display()));
generator.generate(&Source::GlobPattern(schema), &mut buf)?;
let content = String::from_utf8(buf)
.expect("Content of schema files is not a valid UTF-8 string");
fs::write(&path, content)?;
println!("cargo::rerun-if-changed={}", schema);
}
Ok(())
}
}