gclone/src/pgd.rs

131 lines
3.3 KiB
Rust
Raw Normal View History

2019-02-11 20:27:21 +01:00
use std::env;
use std::error::Error;
use std::process::exit;
use std::io::{stdout, stdin, Write};
use std::num::Wrapping;
use colored::*;
2019-02-12 10:47:14 +01:00
use gclone::{Result, Cache};
2019-02-11 17:56:43 +01:00
2019-02-11 20:27:21 +01:00
fn flush_stdout() {
stdout().flush().ok();
}
2019-02-12 10:47:14 +01:00
fn main() -> Result<()> {
2019-02-11 20:27:21 +01:00
let request = match env::args().nth(1) {
Some(arg) => arg,
None => {
eprintln!("{} {}",
"error:".bold().red(),
"cdg expects an argument".bold());
exit(1);
},
};
2019-02-12 10:47:14 +01:00
main_with_cache(&request, true)
2019-02-11 20:51:00 +01:00
}
2019-02-12 10:47:14 +01:00
fn main_with_cache(request: &str, regen: bool) -> Result<()> {
2019-02-11 20:51:00 +01:00
2019-02-12 11:04:04 +01:00
let (cache, regen) = match Cache::read() {
Ok(c) => (c, regen),
Err(_) => (Cache::generate(), false),
};
2019-02-11 20:51:00 +01:00
2019-02-11 20:27:21 +01:00
let matches = cache.find(&request);
match matches.len() {
0 => {
2019-02-11 20:51:00 +01:00
if regen {
eprintln!("{} {}",
"warning:".bold().yellow(),
"directory not found, regenerating cache...".bold());
2019-02-12 11:04:04 +01:00
let cache = Cache::generate();
2019-02-11 20:51:00 +01:00
match cache.write() {
Ok(_) => (),
Err(e) => {
eprintln!("{} {} {}",
"warning:".bold().yellow(),
"couldn't write cache:".bold(),
e.description());
},
}
return main_with_cache(request, false);
} else {
eprintln!("{} {}",
"error:".bold().red(),
"no such directory".bold());
exit(1);
}
2019-02-11 20:27:21 +01:00
},
1 => {
println!("{}", matches[0]);
},
len => {
2019-02-11 20:51:00 +01:00
eprintln!("{}", "info: multiple entries found, please select one".bold());
2019-02-11 20:27:21 +01:00
for (i, j) in matches.iter().enumerate() {
2019-02-11 20:51:00 +01:00
eprintln!("{} {}",
&format!("[{}]", i + 1).bold().blue(),
&format!("{}", j).yellow());
2019-02-11 20:27:21 +01:00
}
2019-02-11 20:51:00 +01:00
eprint!("{}", "Enter your choice: ".bold());
2019-02-11 20:27:21 +01:00
flush_stdout();
let mut string = String::new();
match stdin().read_line(&mut string) {
Ok(_) => (),
Err(e) => {
eprintln!("{} {} {}",
"error:".bold().red(),
"couldn't read line:".bold(),
e.description());
exit(1);
},
};
// Pop the trailing \n of the string
string.pop();
// Use wrapping to move 0 to std::usize::MAX which is ok.
let value = (Wrapping(match string.parse::<usize>() {
Ok(v) => v,
Err(e) => {
eprintln!("{} {} {}",
"error:".bold().red(),
"couldn't parse integer:".bold(),
e.description());
exit(1);
}
}) - Wrapping(1)).0;
if value >= len {
eprintln!("{} {}",
"error:".bold().red(),
"integer wasn't in the right range".bold());
exit(1);
}
println!("{}", matches[value]);
},
}
2019-02-12 10:47:14 +01:00
Ok(())
2019-02-11 20:27:21 +01:00
2019-02-11 17:56:43 +01:00
}
2019-02-11 20:27:21 +01:00