use argh::FromArgs;
use csv::{Reader, ReaderBuilder, Terminator, Trim};
use std::io;
use std::path::PathBuf;
use std::process;
use yansi::{Paint};
mod generators;
mod translations;
use generators::{generate_json, generate_json_fast};
const APP_DESC: &str = "trans·lo·cate, verb, to move from one place to another.";
const MISSING_FILE_ERR: &str = "Please give file path as a command line argument!";
#[derive(FromArgs)]
struct CliArgs {
#[argh(option, short = 'd')]
delimiter: Option<String>,
#[argh(option, short = 'e')]
escape_char: Option<String>,
#[argh(switch, short = 'i')]
inflexible: bool,
#[argh(option, short = 't')]
terminator: Option<String>,
#[argh(switch, short = 'T')]
trim: Option<bool>,
#[argh(switch, short = 'v')]
version: Option<bool>,
#[argh(positional)]
file: Option<String>,
}
fn get_file_location(file: &str) -> Result<PathBuf, io::Error> {
let cwd = std::env::current_dir()?;
let path = file;
let full_path = PathBuf::from(path);
if full_path.has_root() {
Ok(full_path)
} else {
Ok(cwd.join(full_path))
}
}
fn main() -> Result<(), std::io::Error> {
let cli: CliArgs = argh::from_env();
if cli.version.is_some() {
return Ok(println!(
"{} v{}\n{}",
env!("CARGO_PKG_NAME").underline(),
env!("CARGO_PKG_VERSION"),
APP_DESC.italic()
));
}
let file_path = if let Some(file) = &cli.file {
file
} else {
"translations.csv"
};
let csv_path = get_file_location(file_path)?;
let is_tsv = if let Some(val) = csv_path.extension() {
val == "tsv"
} else {
false
};
let delimiter = if let Some(delim) = cli.delimiter {
delim.as_bytes()[0]
} else if is_tsv {
b'\t'
} else {
b','
};
let escape = if let Some(esc) = cli.escape_char {
esc.as_bytes()[0]
} else if is_tsv {
b'\\'
} else {
b'"'
};
let terminator = if let Some(terminate) = cli.terminator {
Terminator::Any(terminate.as_bytes()[0])
} else if is_tsv {
Terminator::Any(b'\n')
} else {
Terminator::CRLF
};
let trim_whitespace = if let Some(trim) = cli.trim {
if trim {
Trim::Fields
} else {
Trim::None
}
} else {
Trim::None
};
let mut reader = ReaderBuilder::new()
.delimiter(delimiter)
.escape(Some(escape))
.flexible(!cli.inflexible)
.terminator(terminator)
.trim(trim_whitespace)
.from_path(&csv_path)?;
let mut reader_count = Reader::from_path(&csv_path)?;
let headings = reader.headers()?.clone();
let rows = reader_count.byte_records().count();
if generate_json_fast(&mut reader, &headings, rows).is_err() {
if let Err(error) = generate_json(&mut reader, &headings, rows) {
println!("{}", error);
process::exit(1);
}
}
Ok(println!("\nConversion successful!"))
}