use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use clap::Parser;
use std::io::Write;
#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
#[clap(propagate_version = true)]
struct Cli {
#[clap(name = "FILE")]
file: PathBuf,
#[clap(short, long)]
download: bool,
#[clap(short, long)]
outfile: Option<PathBuf>,
#[clap(long)]
cache_dir: Option<String>,
#[clap(long)]
cache_force: bool,
#[clap(long)]
cache_file: Option<String>,
#[clap(short, long)]
stats: bool,
}
fn main() {
let cli = Cli::parse();
let path: &str = cli.file.to_str().unwrap();
let outfile: Option<PathBuf> = cli.outfile;
if cli.download {
let out_path = match outfile {
None => {
if !path.starts_with("http") {
eprintln!("{} is not a remote file, skip downloading", path);
return
}
path.split('/').last().unwrap().to_string()
}
Some(p) => {
p.to_str().unwrap().to_string()
}
};
match oneio::download(path, out_path.as_str(), None) {
Ok(_) => {
println!("file successfully downloaded to {}", out_path.as_str());
}
Err(e) => {
eprintln!("file download error: {}", e);
}
}
return
}
let reader = Box::new(
BufReader::new(
match cli.cache_dir {
Some(dir) => {
match oneio::get_cache_reader(path, dir.as_str(), cli.cache_file, cli.cache_force) {
Ok(reader) => {reader}
Err(e) => {
eprintln!("cannot open {}: {}", path, e);
return
}
}
}
None => {
match oneio::get_reader(path) {
Ok(reader) => {reader}
Err(e) => {
eprintln!("cannot open {}: {}", path, e);
return
}
}
}
}
)
);
let mut stdout = std::io::stdout();
let mut count_lines = 0;
let mut count_chars = 0;
for line in reader.lines() {
let line = match line {
Ok(l) => {l}
Err(e) => {
eprintln!("cannot read line from {}: {}", path, e);
return;
}
};
if !cli.stats {
if let Err(e) = writeln!(stdout, "{}", line) {
if e.kind() != std::io::ErrorKind::BrokenPipe {
eprintln!("{}", e);
std::process::exit(1);
}
std::process::exit(0);
}
}
count_chars += line.chars().count();
count_lines += 1;
}
if cli.stats {
println!("lines: \t {}", count_lines);
println!("chars: \t {}", count_chars);
}
}