Skip to content

Commit 51cdd98

Browse files
committed
Closer to a clean working refactor
1 parent 9492026 commit 51cdd98

3 files changed

Lines changed: 102 additions & 80 deletions

File tree

src/cowsay.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::parser::{ParserIterator, TerminalCharacter};
22
use owo_colors::{DynColor, OwoColorize, Style, XtermColors};
33
use std::{collections::HashMap, error::Error, str::from_utf8};
4-
#[cfg(not(feature = "inline-cowsay"))]
54
use std::{
65
fs::{self, File},
7-
io::{self, Read},
6+
io::Read,
87
path::PathBuf,
98
};
109
use strip_ansi_escapes::strip;
@@ -352,40 +351,39 @@ pub fn print_cowsay(
352351
println!("{msg_str}{cow_str}")
353352
}
354353

355-
#[cfg(feature = "inline-cowsay")]
356-
pub fn choose_random_cow(rng: &mut impl Rand) -> String {
357-
let chosen_idx = rng.next_lim_usize(COW_DATA.len());
358-
COW_DATA[chosen_idx].1.to_string()
359-
}
360-
361354
#[cfg(feature = "inline-cowsay")]
362355
pub fn get_cow_by_name(name: &str) -> Option<&str> {
363356
COW_DATA
364357
.into_iter()
365358
.find_map(|item| if item.0 == name { Some(item.1) } else { None })
366359
}
367360

361+
fn get_external_cow(cow_list: &[String], rng: &mut impl Rand) -> String {
362+
let chosen_idx = rng.next_lim_usize(cow_list.len());
363+
364+
let chosen_path = &cow_list[chosen_idx];
365+
match fs::File::open(chosen_path) {
366+
Ok(mut file) => {
367+
let mut cow_str = String::new();
368+
file.read_to_string(&mut cow_str)
369+
.expect("Error reading cow string");
370+
cow_str
371+
}
372+
Err(e) => panic!("{e}"),
373+
}
374+
}
375+
368376
pub fn choose_random_cow(cow_list: &[String], rng: &mut impl Rand) -> String {
369377
cfg_select! {
370378
feature = "inline-cowsay" => {
371-
let chosen_idx = rng.next_lim_usize(cow_list.len());
372-
cow_list[chosen_idx].1.to_string()
373-
}
374-
not(feature = "inline-cowsay") => {
375-
let chosen_idx = rng.next_lim_usize(cow_list.len());
376-
377-
let chosen_path = &cow_list[chosen_idx];
378-
match fs::File::open(chosen_path) {
379-
Ok(mut file) => {
380-
let mut cow_str = String::new();
381-
file.read_to_string(&mut cow_str)
382-
.expect("Error reading cow string");
383-
cow_str
384-
}
385-
Err(e) => panic!("{e}"),
379+
if !cow_list.is_empty() {
380+
get_external_cow(cow_list, rng)
381+
} else {
382+
let chosen_idx = rng.next_lim_usize(COW_DATA.len());
383+
COW_DATA[chosen_idx].1.to_string()
386384
}
387-
388385
}
386+
not(feature = "inline-cowsay") => { get_external_cow(cow_list, rng) }
389387
}
390388
}
391389

@@ -399,7 +397,7 @@ pub fn get_cow_string(cow_files: &[String], rng: &mut impl tinyrand::Rand) -> St
399397
1 => get_cow_by_name(&cow_files[0].as_str())
400398
.expect("Could not find a cow with the specified name in the inlined data")
401399
.to_string(),
402-
_ => choose_random_cow(&COW_DATA, rng)
400+
_ => choose_random_cow(&[], rng)
403401
}
404402
}
405403
not(feature = "inline-cowsay") => {

src/fortune.rs

Lines changed: 77 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
use std::error::Error;
2-
#[cfg(not(feature = "inline-fortune"))]
3-
use std::{
4-
ffi::OsStr,
5-
fs::{self, File},
6-
io::{self, Read},
7-
path::PathBuf,
8-
};
2+
use std::{fs::File, io::Read};
93
use tinyrand::Rand;
104

115
fn check_fortune_constraints(
@@ -34,8 +28,42 @@ fn check_fortune_constraints(
3428
})
3529
}
3630

31+
fn get_external_fortune(
32+
rng: &mut impl Rand,
33+
list: &[String],
34+
include_off: bool,
35+
max_width: Option<u64>,
36+
max_lines: Option<u64>,
37+
) -> Result<String, Box<dyn Error>> {
38+
let file_path = match include_off {
39+
true => {
40+
let idx = rng.next_lim_usize(list.len());
41+
list[idx].clone()
42+
}
43+
false => {
44+
let filtered: Vec<&String> = list.into_iter().filter(|x| !x.contains("off")).collect();
45+
let idx = rng.next_lim_usize(filtered.len());
46+
filtered[idx].clone()
47+
}
48+
};
49+
50+
match File::open(file_path) {
51+
Ok(mut file) => {
52+
let mut string_buf = String::new();
53+
let _result = file.read_to_string(&mut string_buf)?;
54+
let no_cr = string_buf.replace("\r", "");
55+
let split: Vec<&str> = no_cr
56+
.split("\n%\n")
57+
.filter(|element| check_fortune_constraints(element, max_width, max_lines))
58+
.collect();
59+
let chosen_idx = rng.next_lim_usize(split.len());
60+
Ok(split[chosen_idx].to_string())
61+
}
62+
Err(e) => panic!("Could not open Fortune file! {e}"),
63+
}
64+
}
65+
3766
///default method of getting a fortune, without using the index file.
38-
#[cfg(not(feature = "inline-fortune"))]
3967
pub fn get_fortune(
4068
_fortune_files: &[String],
4169
rng: &mut impl Rand,
@@ -45,55 +73,52 @@ pub fn get_fortune(
4573
) -> Result<String, Box<dyn Error>> {
4674
cfg_select! {
4775
feature = "inline-fortune" => {
48-
macro_rules! choose_inline_fortune {
49-
($rng_ident:ident, $list_ident:ident, $max_wid_ident:ident, $max_lines_ident:ident) => {{
50-
let list_iter: Vec<&'static str> = $list_ident
51-
.into_iter()
52-
.filter(|element| {
53-
check_fortune_constraints(element, $max_wid_ident, $max_lines_ident)
54-
})
55-
.collect();
56-
let chosen_idx = $rng_ident.next_lim_usize(list_iter.len());
57-
Ok($list_ident[chosen_idx].to_string())
58-
}};
59-
}
60-
61-
cfg_if::cfg_if! {
62-
if #[cfg(feature="inline-off-fortune")]{
63-
if include_offensive {
64-
let weight_off:f64 = OFF_FORTUNE_LIST.len() as f64/(FORTUNE_LIST.len() as f64 + OFF_FORTUNE_LIST.len() as f64);
65-
match rng.next_bool(weight_off.into()){
66-
true => choose_inline_fortune!(rng, OFF_FORTUNE_LIST, max_width, max_lines),
67-
false => choose_inline_fortune!(rng, FORTUNE_LIST, max_width, max_lines),
68-
}
69-
} else {
70-
choose_inline_fortune!(rng, FORTUNE_LIST, max_width, max_lines)
76+
if !_fortune_files.is_empty(){
77+
get_external_fortune(
78+
rng,
79+
_fortune_files,
80+
include_offensive,
81+
max_width,
82+
max_lines
83+
)
84+
} else {
85+
let list = match include_offensive {
86+
true => {
87+
cfg_select! {
88+
feature = "inline-off-fortune" => {
89+
if include_offensive {
90+
let weight_off:f64 = OFF_FORTUNE_LIST.len() as f64/(FORTUNE_LIST.len() as f64 + OFF_FORTUNE_LIST.len() as f64);
91+
match rng.next_bool(weight_off.into()){
92+
true => OFF_FORTUNE_LIST,
93+
false => FORTUNE_LIST,
94+
}
95+
} else {
96+
FORTUNE_LIST
97+
}
98+
}
99+
not(feature = "inline-off-fortune") => { FORTUNE_LIST }
100+
}
71101
}
72-
} else {
73-
let _ = include_offensive;
74-
choose_inline_fortune!(rng, FORTUNE_LIST, max_width, max_lines)
75-
}
102+
false => FORTUNE_LIST,
103+
};
104+
105+
let list_iter: Vec<&'static str> = list
106+
.into_iter()
107+
.filter(|element| check_fortune_constraints(element, max_width, max_lines))
108+
.collect();
109+
let chosen_idx = rng.next_lim_usize(list_iter.len());
110+
Ok(list[chosen_idx].to_string())
76111
}
77112

78113
}
79114
not(feature = "inline-fortune") => {
80-
// TODO Choose the file to open, exclude offensive as necessary
81-
82-
match File::open(file_path) {
83-
Ok(mut file) => {
84-
let mut string_buf = String::new();
85-
let _result = file.read_to_string(&mut string_buf)?;
86-
let no_cr = string_buf.replace("\r", "");
87-
let split: Vec<&str> = no_cr
88-
.split("\n%\n")
89-
.filter(|element| check_fortune_constraints(element, max_width, max_lines))
90-
.collect();
91-
let chosen_idx = rng.next_lim_usize(split.len());
92-
Ok(split[chosen_idx].to_string())
93-
}
94-
Err(e) => panic!("Could not open Fortune file! {e}"),
95-
}
96-
115+
get_external_fortune(
116+
rng,
117+
_fortune_files,
118+
include_offensive,
119+
max_width,
120+
max_lines
121+
)
97122
}
98123
}
99124
}

src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ mod fortune;
44
mod parser;
55

66
use cli::Options;
7-
use cowsay::{
8-
CowVariant, SpeechBubble, get_cow_names, get_cow_string, print_cowsay, random_cow_variant,
9-
};
7+
use cowsay::{CowVariant, SpeechBubble, get_cow_string, print_cowsay, random_cow_variant};
108

119
use tinyrand::{Seeded, StdRand};
1210

@@ -44,6 +42,7 @@ fn main() {
4442
_ => options.cow_variant,
4543
};
4644

45+
//TODO why did I do this
4746
let max_width = match options.max_width {
4847
Some(val) => val as usize,
4948
None => 64usize,

0 commit comments

Comments
 (0)