pub fn metrics(content: &str) -> (u64, u64, u64) {
let lines = content.lines().count() as u64;
let words = content.split_whitespace().count() as u64;
let chars = content.chars().count() as u64;
(lines, words, chars)
}
pub fn within(value: u64, min: Option<u64>, max: Option<u64>) -> bool {
min.is_none_or(|m| value >= m) && max.is_none_or(|m| value <= m)
}
pub fn parent_dir(rel: &str) -> String {
match rel.rsplit_once('/') {
Some((dir, _)) => dir.to_string(),
None => ".".to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn metrics_count_lines_words_chars() {
assert_eq!(metrics("a b\ncd\n"), (2, 3, 7));
assert_eq!(metrics("one two"), (1, 2, 7));
assert_eq!(metrics(""), (0, 0, 0));
}
#[test]
fn within_bounds() {
assert!(within(10, Some(5), Some(20)));
assert!(!within(3, Some(5), None));
assert!(!within(30, None, Some(20)));
assert!(within(10, None, None));
}
#[test]
fn parent_dir_of_paths() {
assert_eq!(parent_dir("a/b/c.rs"), "a/b");
assert_eq!(parent_dir("top.rs"), ".");
}
}