mod barbfile; mod executor; mod output; use barbfile::BarbFile; use clap::Parser; use dotenv::dotenv; use env_logger; use executor::{Context, Executor}; use log::debug; use output::BarbOutput; use std::env; use std::slice::Iter; #[derive(Parser, Debug)] #[clap(version)] struct Args { #[clap(short, long)] headers: bool, #[clap(short, long)] all_headers: bool, #[clap(short, long)] body: bool, #[clap(short, long)] raw: bool, #[clap(short, long)] filter: Option, #[clap(short, long)] no_color: bool, #[clap(short = 'F', long)] no_filter: bool, #[clap(long)] hdr: Vec, files: Vec, } impl Args { pub fn files_iter(&self) -> Iter { self.files.iter() } pub fn jq_filter(&self) -> &Option { &self.filter } pub fn no_filter(&self) -> bool { self.no_filter } pub fn hdrs(&self) -> Vec<(String, String)> { self.hdr .iter() .map(|x| x.split_once('=')) .filter(|x| x.is_some()) .map(|x| { let (def, val) = x.unwrap(); (String::from(def), String::from(val)) }) .collect::>() } pub fn output(&self) -> BarbOutput { BarbOutput::new( !self.body, self.all_headers, self.headers || self.all_headers || !self.body, !self.headers || self.body, self.raw, !self.no_color, ) } } fn read_file_barb(file_name: &str) -> Result { BarbFile::from_file(file_name.to_string()) .map_err(|_| format!("Failed to parse file {}", file_name)) } fn main() { env_logger::init(); let args = Args::parse(); debug!("args: {:?}", args); dotenv().ok(); let mut executor = Executor::new(Context::new(env::vars())); let output = args.output(); let files: Vec> = args.files_iter().map(|x| read_file_barb(x)).collect(); type MaybeBarbFiles = Vec>; let (maybe_deps, errors): (MaybeBarbFiles, MaybeBarbFiles) = files .iter() .map(|x| match x.as_ref().ok() { Some(bfile) => bfile.dependency(), None => None, }) .filter(|x| x.is_some()) .map(|x| read_file_barb(&x.unwrap())) .partition(|x| x.is_ok()); for e in errors { println!("{}", e.err().unwrap()); } let mut dependencies = maybe_deps .iter() .map(|x| x.as_ref().unwrap()) .collect::>(); dependencies.sort(); dependencies.dedup(); for dep in dependencies { match executor.execute_dep(dep, &output) { Ok(()) => (), Err(err) => println!("{}", err), } } for bfile in files { if let Err(e) = bfile { println!("{}", e); continue; } match executor.execute( &bfile.unwrap(), &output, args.jq_filter(), args.no_filter(), args.hdrs(), ) { Ok(()) => (), Err(err) => println!("{}", err), } } }