use clap::{App, Arg, ArgMatches, SubCommand, AppSettings};
use xron::Error;
fn app() -> App<'static, 'static> {
App::new("xron")
.about("Converts XLSX files to RON")
.author("Thomas Schaller")
.setting(AppSettings::ArgsNegateSubcommands)
.setting(AppSettings::SubcommandsNegateReqs)
.arg(
Arg::with_name("INPUT_FILE")
.required(true)
.takes_value(true)
.value_name("INPUT_FILE")
.index(1),
)
.arg(
Arg::with_name("reverse")
.help("Converts RON to XLSX")
.short("r")
.long("reverse")
.requires("output-file"),
)
.arg(
Arg::with_name("skip-empty")
.help("Does not insert empty rows into XLSX")
.long("skip-empty")
.requires("reverse"),
)
.arg(
Arg::with_name("column-width")
.help("Sets column width for XLSX")
.long("column-width")
.requires("reverse")
.takes_value(true)
.value_name("COLUMN_WIDTH"),
)
.arg(
Arg::with_name("output-file")
.short("o")
.long("output-file")
.takes_value(true)
.value_name("OUTPUT_TO_FILE"),
)
.subcommand(
SubCommand::with_name("intersect")
.about("Only keep intersect rows")
.arg(
Arg::with_name("BASE_FILE")
.help("Base file to remove rows from")
.required(true)
.takes_value(true)
.value_name("BASE_FILE")
.index(1),
)
.arg(
Arg::with_name("CMP_FILE")
.help("File to compare rows to")
.required(true)
.takes_value(true)
.value_name("CMP_FILE")
.index(2),
)
.arg(
Arg::with_name("output-file")
.short("o")
.long("output-file")
.takes_value(true)
.value_name("OUTPUT_TO_FILE"),
),
)
}
fn core(matches: &ArgMatches<'_>) -> Result<(), Error> {
let file = matches.value_of("INPUT_FILE").unwrap();
if matches.is_present("reverse") {
let skip_empty = matches.is_present("skip-empty");
let column_width = matches.value_of("skip-empty").unwrap_or("60.0");
let column_width = column_width.parse().unwrap_or(60.0);
let output_file = matches.value_of("output-file").unwrap();
let ron_workbook = xron::RonWorkbook::read_ron(file)?;
ron_workbook.write_xlsx(output_file, column_width, skip_empty)?;
} else {
let ron_workbook = xron::RonWorkbook::read_xlsx(file)?;
let serialized = ron::ser::to_string_pretty(&ron_workbook, Default::default())?;
println!("{}", serialized);
if let Some(file) = matches.value_of("output-file") {
std::fs::write(file, serialized.as_bytes())?;
}
}
Ok(())
}
fn unique(matches: &ArgMatches<'_>) -> Result<(), Error> {
let base_file = matches.value_of("BASE_FILE").unwrap();
let cmp_file = matches.value_of("CMP_FILE").unwrap();
let mut base_workbook = xron::RonWorkbook::read_xlsx(base_file)?;
let cmp_workbook = xron::RonWorkbook::read_xlsx(cmp_file)?;
base_workbook.retain_unique(&cmp_workbook);
let serialized = ron::ser::to_string_pretty(&base_workbook, Default::default())?;
println!("{}", serialized);
if let Some(file) = matches.value_of("output-file") {
std::fs::write(file, serialized.as_bytes())?;
}
Ok(())
}
fn run() -> Result<(), Error> {
let app = app();
let matches = app.get_matches();
match matches.subcommand() {
("intersect", Some(sm)) => unique(sm)?,
_ => core(&matches)?,
}
Ok(())
}
fn main() {
if let Err(e) = run() {
eprintln!("Error: {}", e);
}
}