1mod cache;
4mod formatting;
5
6pub use cache::Cache;
7pub use formatting::*;
8
9use crate::core::ForgeGuardError;
10
11pub fn cpu_count() -> usize {
13 std::thread::available_parallelism()
14 .map(|n| n.get())
15 .unwrap_or(4)
16}
17
18pub fn truncate(s: &str, max_len: usize) -> String {
20 if s.len() <= max_len {
21 s.to_string()
22 } else {
23 format!("{}...", &s[..max_len.saturating_sub(3)])
24 }
25}
26
27pub fn read_file_trimmed(path: &std::path::Path) -> Result<String, ForgeGuardError> {
29 let content = std::fs::read_to_string(path)?;
30 Ok(content.trim().to_string())
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn test_cpu_count() {
39 let count = cpu_count();
40 assert!(count >= 1);
41 }
42
43 #[test]
44 fn test_truncate_short_string() {
45 assert_eq!(truncate("hello", 10), "hello");
46 }
47
48 #[test]
49 fn test_truncate_long_string() {
50 let result = truncate("hello world this is long", 10);
51 assert_eq!(result, "hello w...");
52 assert_eq!(result.len(), 10);
53 }
54
55 #[test]
56 fn test_truncate_exact() {
57 assert_eq!(truncate("hello", 5), "hello");
58 }
59
60 #[test]
61 fn test_truncate_empty() {
62 assert_eq!(truncate("", 5), "");
63 }
64
65 #[test]
66 fn test_format_duration_ms() {
67 let result = format_duration(0.05);
68 assert!(result.contains("50ms") || result.contains("0ms"));
69 }
70
71 #[test]
72 fn test_format_duration_seconds() {
73 let result = format_duration(5.5);
74 assert_eq!(result, "5.5s");
75 }
76
77 #[test]
78 fn test_format_duration_minutes() {
79 let result = format_duration(125.0);
80 assert_eq!(result, "2m 5s");
81 }
82
83 #[test]
84 fn test_format_duration_hours() {
85 let result = format_duration(3661.0);
86 assert_eq!(result, "1h 1m");
87 }
88
89 #[test]
90 fn test_format_number() {
91 assert_eq!(format_number(0), "0");
92 assert_eq!(format_number(100), "100");
93 assert_eq!(format_number(1000), "1,000");
94 assert_eq!(format_number(1000000), "1,000,000");
95 }
96
97 #[test]
98 fn test_format_pct() {
99 assert_eq!(format_pct(0.5), "50.0%");
100 assert_eq!(format_pct(1.0), "100.0%");
101 assert_eq!(format_pct(0.0), "0.0%");
102 }
103
104 #[test]
105 fn test_format_bytes() {
106 assert_eq!(format_bytes(0), "0 B");
107 assert_eq!(format_bytes(500), "500 B");
108 let kb = format_bytes(2048);
109 assert!(kb.contains("KB") || kb.contains("2.00"));
110 let mb = format_bytes(1048576);
111 assert!(mb.contains("MB") || mb.contains("1.00"));
112 }
113}