demit 1.0.0

A flexible data generator for various domains
Documentation
use demit::cli;
use demit::domain::{self, PosRecord, Record, WeblogRecord};
use demit::error::Result;
use demit::output;
use log::debug;
use std::fs::File;
use std::io;

fn main() -> Result<()> {
    let args = cli::parse_args();

    // log level
    let mut builder = env_logger::Builder::from_env("DEMIT_LOG");

    if args.verbose {
        builder.filter(None, log::LevelFilter::Debug);
    }

    builder.init();

    debug!("Parsed command line arguments: {:?}", args);

    // writer is either a file or stdout
    // the default is stdout
    let writer = get_writer(args.output.as_deref())?;
    debug!("Writer initialized with output path: {:?}", args.output);

    debug!(
        "Generating {} records for domain: {:?}",
        args.count, args.domain
    );
    match args.domain {
        domain::DomainType::Pos => {
            generate_and_write::<PosRecord>(writer, args.count, args.format)
        }
        domain::DomainType::Weblog => {
            generate_and_write::<WeblogRecord>(writer, args.count, args.format)
        }
    }
}

/// Get the appropriate writer based on output path
fn get_writer(output_path: Option<&str>) -> Result<Box<dyn io::Write>> {
    // Box<> is required here because we need to return 2 different types
    // which implement io::Write
    match output_path {
        Some(path) => Ok(Box::new(File::create(path)?)),
        None => Ok(Box::new(io::stdout())),
    }
}

/// Generate records and write them in the specified format
fn generate_and_write<T: Record>(
    mut writer: Box<dyn io::Write>,
    count: usize,
    format: output::OutputFormat,
) -> Result<()> {
    debug!("Generating {} records with format {:?}", count, format);
    let records = T::generate(count);
    debug!("Generated {} records successfully", records.len());
    output::write_data(&mut writer, &records, format)
}