1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::{BoxResult, ConfigFile, ConfigFileVec, IOResult, DEFAULT_IGNORE_CHARS};
use rand::{
distributions::{Alphanumeric, Standard},
prelude::Distribution,
Rng,
};
use std::io::{BufRead, BufReader};
use std::{
fs::File,
path::{Path, PathBuf},
str::FromStr,
};
pub fn collect_files_as<T>(f: &dyn Fn(PathBuf) -> T, pat: &str) -> BoxResult<Vec<T>> {
let mut files = Vec::<T>::new();
for r in glob::glob(pat)? {
files.push(f(r?))
}
Ok(files)
}
pub fn collect_config_files(pattern: &str, required: bool) -> ConfigFileVec {
let f = |p: std::path::PathBuf| ConfigFile::from(p).required(required);
collect_files_as(&f, pattern).expect("Failed to find any similar files...")
}
pub fn extractor<S: ToString, T: FromStr + ToString>(
bp: char,
data: &S,
exclude: Option<&[char]>,
) -> Vec<T>
where
<T as FromStr>::Err: std::fmt::Debug,
{
let data = data.to_string();
let skip = exclude.unwrap_or(DEFAULT_IGNORE_CHARS);
let trimmed: &str = data.trim_matches(skip);
trimmed
.split(bp)
.map(|i| i.trim_matches(skip).parse::<T>().unwrap())
.collect()
}
pub fn file_to_vec(fp: String) -> IOResult<Vec<String>> {
let file_in = File::open(fp)?;
let file_reader = BufReader::new(file_in);
Ok(file_reader.lines().filter_map(IOResult::ok).collect())
}
pub fn fnl_remove<T: Clone + ToString>(data: T) -> String {
let data = data.to_string();
let mut chars = data.chars();
chars.next();
chars.next_back();
chars.as_str().to_string()
}
pub fn generate_random_number<T>() -> T
where
Standard: Distribution<T>,
{
let mut rnd = rand::thread_rng();
rnd.gen::<T>()
}
pub fn generate_random_string(len: usize) -> String {
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(len)
.map(char::from)
.collect()
}
pub fn is_float<T: ToString>(data: &T) -> bool {
f64::from_str(&data.to_string()).is_ok()
}
pub fn package_name() -> String {
env!("CARGO_PKG_NAME").to_string()
}
pub fn project_root() -> PathBuf {
Path::new(&env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(1)
.unwrap()
.to_path_buf()
}
pub fn try_collect_config_files(pattern: &str, required: bool) -> BoxResult<ConfigFileVec> {
let f = |p: PathBuf| ConfigFile::from(p).required(required);
collect_files_as(&f, pattern)
}
pub fn try_str_to_socketaddr(
addr: impl ToString,
) -> Result<std::net::SocketAddr, std::net::AddrParseError> {
addr.to_string().parse()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_file_to_vec() {
let fp = "../README.md".to_string();
let a = file_to_vec(fp);
let b = try_collect_config_files("**/Cargo.*", false);
assert!(a.is_ok());
assert!(b.is_ok());
assert!(!a.expect("").is_empty())
}
#[test]
fn test_is_float() {
let data = vec!["1", "-10", "ifjuka87"];
assert!(is_float(&data[0]));
assert!(is_float(&data[1]));
assert!(!is_float(&data[2]))
}
}