Allow multiple cookie files, add the -c parameter and improve error handling

This commit is contained in:
runebaas 2019-10-31 01:14:46 +01:00
parent b51dd59ceb
commit 7edc874061
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
6 changed files with 103 additions and 16 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/target /target
**/*.rs.bk **/*.rs.bk
/.idea /.idea
/cookies

View file

@ -3,7 +3,6 @@ mod utils;
use crate::utils::*; use crate::utils::*;
use clap::{App, Arg}; use clap::{App, Arg};
use rand::prelude::*;
fn main() { fn main() {
// specify app // specify app
@ -48,11 +47,23 @@ fn main() {
.arg(Arg::with_name("case_insensitive") .arg(Arg::with_name("case_insensitive")
.short("i") .short("i")
.help("Ignore case for -m patterns. ") .help("Ignore case for -m patterns. ")
.takes_value(false))
.arg(Arg::with_name("show_cookie")
.short("c")
.help("Show the cookie file from which the fortune came.")
.takes_value(false)); .takes_value(false));
let options = options_parser::parse(app); let options = options_parser::parse(app);
// get fortunes // get fortunes
let mut fortunes = fortunes_reader::get_all(options.filename.clone()); let cookie = match fortunes_reader::get_random_cookie() {
Some(fortunes) => fortunes,
None => {
println!("No fortune files found");
std::process::exit(1);
}
};
let mut fortunes = cookie.fortunes;
// filter by max length // filter by max length
if options.short_fortunes || options.long_fortunes { if options.short_fortunes || options.long_fortunes {
@ -65,7 +76,18 @@ fn main() {
} }
// get a random one // get a random one
let the_fortune = get_random_fortune(fortunes); let the_fortune = match helpers::get_random_from_vec(fortunes) {
Some(f) => f,
None => {
println!("No fortunes found with these parameters");
std::process::exit(1);
}
};
// reveal the cookie
if options.show_cookie {
println!("({})\n%", cookie.name);
}
// print it ✨ // print it ✨
println!("{}", the_fortune); println!("{}", the_fortune);
@ -74,13 +96,3 @@ fn main() {
waiter::wait(the_fortune) waiter::wait(the_fortune)
} }
} }
fn get_random_fortune(fortunes: Vec<String>) -> String {
let total_fortunes = fortunes.len();
if total_fortunes == 0 {
return "No Fortunes found with these parameters...".to_owned();
}
let random_fortune = rand::thread_rng().gen_range(0, total_fortunes);
fortunes.get(random_fortune).unwrap().trim().to_owned()
}

View file

@ -1,12 +1,67 @@
use crate::utils::helpers::{get_random_from_vec, own_vec};
use std::{fs, path, process}; use std::{fs, path, process};
pub fn get_all(filename: String) -> Vec<String> { pub fn get_random_cookie() -> Option<Cookie> {
let fortune_files = find_fortune_files();
if let Some(selected_file) = get_random_from_vec(fortune_files) {
let fortunes = read_fortune_file(&selected_file);
let cookie = Cookie {
name: selected_file,
fortunes,
};
Some(cookie)
} else {
None
}
}
fn find_fortune_files() -> Vec<String> {
let locations = get_paths();
let mut all_files: Vec<String> = vec![];
for loc in locations {
let full_path = path::Path::new(&loc);
if full_path.exists() {
if let Ok(files) = fs::read_dir(full_path.canonicalize().unwrap()) {
for file in files {
if let Ok(f) = file {
if is_fortfile(&f.path().to_str().unwrap()) {
all_files.push(f.path().to_str().unwrap().to_owned());
}
}
}
}
}
}
all_files
}
fn is_fortfile(path: &str) -> bool {
!path.contains('.')
}
fn read_fortune_file(filename: &str) -> Vec<String> {
if !path::Path::new(&filename).exists() { if !path::Path::new(&filename).exists() {
println!("File '{}' does not found", filename); println!("File '{}' does not found", filename);
process::exit(1); process::exit(1);
} }
let fortune_file = fs::read_to_string(filename).expect("Cannot read fortune file"); let fortune_file = fs::read_to_string(filename).expect("Cannot read fortune file");
let fortunes: Vec<String> = fortune_file.split('%').map(ToOwned::to_owned).collect();
fortunes fortune_file.split('%').map(ToOwned::to_owned).collect()
}
#[cfg(windows)]
fn get_paths() -> Vec<String> {
own_vec(vec!["./fortunes", "./cookies"])
}
#[cfg(unix)]
fn get_paths() -> Vec<String> {
own_vec(vec!["./fortunes", "./cookies", "/lib/share/games/fortunes"])
}
pub struct Cookie {
pub name: String,
pub fortunes: Vec<String>,
} }

15
src/utils/helpers.rs Normal file
View file

@ -0,0 +1,15 @@
use rand::*;
pub fn get_random_from_vec(vector: Vec<String>) -> Option<String> {
let length = vector.len();
if length == 0 {
return None;
}
let random_element = rand::thread_rng().gen_range(0, length);
Some(vector.get(random_element).unwrap().trim().to_owned())
}
pub fn own_vec(input: Vec<&str>) -> Vec<String> {
input.into_iter().map(ToOwned::to_owned).collect()
}

View file

@ -1,3 +1,4 @@
pub mod fortunes_reader; pub mod fortunes_reader;
pub mod helpers;
pub mod options_parser; pub mod options_parser;
pub mod waiter; pub mod waiter;

View file

@ -17,6 +17,7 @@ pub fn parse(app: App) -> Parameters {
None => String::new(), None => String::new(),
}, },
case_insensitive: matches.is_present("case_insensitive"), case_insensitive: matches.is_present("case_insensitive"),
show_cookie: matches.is_present("show_cookie"),
}; };
options options
@ -33,4 +34,6 @@ pub struct Parameters {
pub pattern: String, pub pattern: String,
pub case_insensitive: bool, pub case_insensitive: bool,
pub show_cookie: bool,
} }