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
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
/.idea
|
/.idea
|
||||||
|
/cookies
|
||||||
|
|
38
src/main.rs
38
src/main.rs
|
@ -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()
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
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 fortunes_reader;
|
||||||
|
pub mod helpers;
|
||||||
pub mod options_parser;
|
pub mod options_parser;
|
||||||
pub mod waiter;
|
pub mod waiter;
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue