1#[must_use]
19pub fn calculate_bandwidth(total_bytes: u64, elapsed_secs: f64) -> f64 {
20 if elapsed_secs > 0.0 {
21 (total_bytes as f64 * 8.0) / elapsed_secs
22 } else {
23 0.0
24 }
25}
26
27#[must_use]
39pub fn determine_stream_count(single: bool) -> usize {
40 if single { 1 } else { 4 }
41}
42
43#[must_use]
53pub fn format_distance(km: f64) -> String {
54 if km < 100.0 {
55 format!("{km:.1} km")
56 } else {
57 format!("{km:.0} km")
58 }
59}
60
61#[must_use]
72pub fn format_data_size(bytes: u64) -> String {
73 if bytes < 1024 * 1024 {
74 format!("{:.1} KB", bytes as f64 / 1024.0)
75 } else if bytes < 1024 * 1024 * 1024 {
76 format!("{:.1} MB", bytes as f64 / (1024.0 * 1024.0))
77 } else {
78 format!("{:.2} GB", bytes as f64 / (1024.0 * 1024.0 * 1024.0))
79 }
80}
81
82#[must_use]
92pub fn is_valid_ipv4(s: &str) -> bool {
93 let parts: Vec<&str> = s.split('.').collect();
94 if parts.len() != 4 {
95 return false;
96 }
97 parts.iter().all(|p| p.parse::<u8>().is_ok())
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_calculate_bandwidth_normal() {
106 assert_eq!(calculate_bandwidth(10_000_000, 2.0), 40_000_000.0);
107 }
108
109 #[test]
110 fn test_calculate_bandwidth_zero_elapsed() {
111 assert_eq!(calculate_bandwidth(10_000_000, 0.0), 0.0);
112 }
113
114 #[test]
115 fn test_determine_stream_count_single() {
116 assert_eq!(determine_stream_count(true), 1);
117 }
118
119 #[test]
120 fn test_determine_stream_count_multi() {
121 assert_eq!(determine_stream_count(false), 4);
122 }
123
124 #[test]
125 fn test_format_distance_under_100() {
126 assert_eq!(format_distance(50.5), "50.5 km");
127 assert_eq!(format_distance(99.9), "99.9 km");
128 }
129
130 #[test]
131 fn test_format_distance_100_plus() {
132 assert_eq!(format_distance(100.0), "100 km");
133 assert_eq!(format_distance(150.5), "150 km");
134 }
135
136 #[test]
137 fn test_format_data_size_bytes() {
138 assert!(format_data_size(512).contains("KB"));
139 }
140
141 #[test]
142 fn test_format_data_size_kilobytes() {
143 assert!(format_data_size(500 * 1024).contains("KB"));
144 }
145
146 #[test]
147 fn test_format_data_size_megabytes() {
148 assert!(format_data_size(10 * 1024 * 1024).contains("MB"));
149 }
150
151 #[test]
152 fn test_format_data_size_gigabytes() {
153 assert!(format_data_size(4 * 1024 * 1024 * 1024).contains("GB"));
154 }
155
156 #[test]
157 fn test_is_valid_ipv4_valid() {
158 assert!(is_valid_ipv4("192.168.1.1"));
159 assert!(is_valid_ipv4("0.0.0.0"));
160 assert!(is_valid_ipv4("255.255.255.255"));
161 }
162
163 #[test]
164 fn test_is_valid_ipv4_invalid() {
165 assert!(!is_valid_ipv4("256.1.1.1"));
166 assert!(!is_valid_ipv4("1.2.3"));
167 assert!(!is_valid_ipv4("abc"));
168 assert!(!is_valid_ipv4(""));
169 assert!(!is_valid_ipv4("1.2.3.4.5"));
170 }
171}