use grop::{Config, MergeConfig};
use log;
use serde::Deserialize;
use std::fs;
use std::path::PathBuf;
use std::process::exit;
use structopt::StructOpt;
extern crate stderrlog;
#[derive(Debug, StructOpt, Deserialize)]
#[structopt(name = "grop", about = "A grok powered grep-like utility")]
pub struct Opt {
#[structopt(parse(from_os_str))]
input: Option<PathBuf>,
#[structopt(short, long)]
pattern: Option<Vec<String>>,
#[structopt(short, long)]
list_pattern: Option<Option<String>>,
#[structopt(short, long)]
expression: Option<String>,
#[structopt(short, long, requires_all=&["merge-exp-start", "merge-exp-end"])]
merge_field: Option<Vec<String>>,
#[structopt(long, requires_all=&["merge-exp-end", "merge-field"])]
merge_exp_start: Option<String>,
#[structopt(long, requires_all=&["merge-exp-start", "merge-field"])]
merge_exp_end: Option<String>,
#[structopt(long)]
merge_scope_exclusive: bool,
#[structopt(long)]
filter: Option<Vec<String>>,
#[structopt(short, long)]
output_format: Option<String>,
#[structopt(short, long)]
pub quiet: bool,
#[structopt(short, long, parse(from_occurrences))]
pub verbose: usize,
#[structopt(long = "config", parse(from_os_str))]
config_file: Option<PathBuf>,
}
impl Into<Config> for Opt {
fn into(self) -> Config {
Config {
input: self.input,
custom_patterns: self.pattern,
list_pattern: self.list_pattern,
match_expression: self.expression,
merge_config: match (
&self.merge_field,
&self.merge_exp_start,
&self.merge_exp_end,
) {
(None, None, None) => None,
_ => Some(MergeConfig {
merge_fields: self.merge_field,
merge_exp_start: self.merge_exp_start,
merge_exp_end: self.merge_exp_end,
merge_scope_exclusive: self.merge_scope_exclusive,
}),
},
filters: self.filter,
output_format: self.output_format,
}
}
}
fn main() {
let opt = Opt::from_args();
stderrlog::new()
.verbosity(opt.verbose)
.quiet(opt.quiet)
.init()
.unwrap();
let config: Config;
if let Some(config_file) = &opt.config_file {
let content = fs::read_to_string(config_file).expect("failed to read config file");
let cfg: Config = toml::from_str(&content).expect("failed to parse config file");
config = cfg.merge(opt.into());
} else {
config = opt.into();
}
if let Err(err) = grop::run(config) {
log::error!("{}", err);
exit(1);
}
}