Allow multiple cookie files, add the -c parameter and improve error handling
This commit is contained in:
parent
b51dd59ceb
commit
7edc874061
6 changed files with 103 additions and 16 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/target
|
||||
**/*.rs.bk
|
||||
/.idea
|
||||
/cookies
|
||||
|
|
38
src/main.rs
38
src/main.rs
|
@ -3,7 +3,6 @@ mod utils;
|
|||
|
||||
use crate::utils::*;
|
||||
use clap::{App, Arg};
|
||||
use rand::prelude::*;
|
||||
|
||||
fn main() {
|
||||
// specify app
|
||||
|
@ -48,11 +47,23 @@ fn main() {
|
|||
.arg(Arg::with_name("case_insensitive")
|
||||
.short("i")
|
||||
.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));
|
||||
let options = options_parser::parse(app);
|
||||
|
||||
// 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
|
||||
if options.short_fortunes || options.long_fortunes {
|
||||
|
@ -65,7 +76,18 @@ fn main() {
|
|||
}
|
||||
|
||||
// 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 ✨
|
||||
println!("{}", the_fortune);
|
||||
|
@ -74,13 +96,3 @@ fn main() {
|
|||
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()
|
||||
}
|
||||
|
|
|
@ -1,12 +1,67 @@
|
|||
use crate::utils::helpers::{get_random_from_vec, own_vec};
|
||||
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() {
|
||||
println!("File '{}' does not found", filename);
|
||||
process::exit(1);
|
||||
}
|
||||
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
15
src/utils/helpers.rs
Normal 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()
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod fortunes_reader;
|
||||
pub mod helpers;
|
||||
pub mod options_parser;
|
||||
pub mod waiter;
|
||||
|
|
|
@ -17,6 +17,7 @@ pub fn parse(app: App) -> Parameters {
|
|||
None => String::new(),
|
||||
},
|
||||
case_insensitive: matches.is_present("case_insensitive"),
|
||||
show_cookie: matches.is_present("show_cookie"),
|
||||
};
|
||||
|
||||
options
|
||||
|
@ -33,4 +34,6 @@ pub struct Parameters {
|
|||
|
||||
pub pattern: String,
|
||||
pub case_insensitive: bool,
|
||||
|
||||
pub show_cookie: bool,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue