Skip to content

Commit bbeeab6

Browse files
authored
cleanup clippy warnings, add simple tests (#2)
* cleanup clippy warnings, add simple tests
1 parent 33814db commit bbeeab6

6 files changed

Lines changed: 83 additions & 48 deletions

File tree

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ categories = ["command-line-utilities", "network-programming"]
1414
[dependencies]
1515
ratatui = "0.26"
1616
crossterm = "0.27"
17-
rand = "0.9.2"
17+
rand = "0.9.2"
18+
19+
[lints.clippy]
20+
pedantic = "deny"

src/discovery/fake.rs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,41 @@
11
use crate::types::{AdapterInfo, PortCounters, PortInfo};
22
use std::sync::atomic::{AtomicU64, Ordering};
33

4-
static BASE_RX_BYTES_0: AtomicU64 = AtomicU64::new(1234567890);
5-
static BASE_TX_BYTES_0: AtomicU64 = AtomicU64::new(987654321);
6-
static BASE_RX_PACKETS_0: AtomicU64 = AtomicU64::new(1000000);
7-
static BASE_TX_PACKETS_0: AtomicU64 = AtomicU64::new(950000);
4+
static BASE_RX_BYTES_0: AtomicU64 = AtomicU64::new(1_234_567_890);
5+
static BASE_TX_BYTES_0: AtomicU64 = AtomicU64::new(987_654_321);
6+
static BASE_RX_PACKETS_0: AtomicU64 = AtomicU64::new(1_000_000);
7+
static BASE_TX_PACKETS_0: AtomicU64 = AtomicU64::new(950_000);
88
static BASE_RX_ERRORS_0: AtomicU64 = AtomicU64::new(12);
99
static BASE_TX_ERRORS_0: AtomicU64 = AtomicU64::new(5);
1010

11-
static BASE_RX_BYTES_1: AtomicU64 = AtomicU64::new(5555555555);
12-
static BASE_TX_BYTES_1: AtomicU64 = AtomicU64::new(4444444444);
13-
static BASE_RX_PACKETS_1: AtomicU64 = AtomicU64::new(2500000);
14-
static BASE_TX_PACKETS_1: AtomicU64 = AtomicU64::new(2400000);
11+
static BASE_RX_BYTES_1: AtomicU64 = AtomicU64::new(5_555_555_555);
12+
static BASE_TX_BYTES_1: AtomicU64 = AtomicU64::new(4_444_444_444);
13+
static BASE_RX_PACKETS_1: AtomicU64 = AtomicU64::new(2_500_000);
14+
static BASE_TX_PACKETS_1: AtomicU64 = AtomicU64::new(2_400_000);
1515
static BASE_RX_ERRORS_1: AtomicU64 = AtomicU64::new(8);
1616
static BASE_TX_ERRORS_1: AtomicU64 = AtomicU64::new(3);
1717
static BASE_RX_DROPPED_1: AtomicU64 = AtomicU64::new(1);
1818

1919
pub fn generate_fake_adapters() -> Vec<AdapterInfo> {
20-
let rx_bytes_0 = BASE_RX_BYTES_0.fetch_add(rand::random::<u64>() % 100000, Ordering::Relaxed);
21-
let tx_bytes_0 = BASE_TX_BYTES_0.fetch_add(rand::random::<u64>() % 80000, Ordering::Relaxed);
20+
let rx_bytes_0 = BASE_RX_BYTES_0.fetch_add(rand::random::<u64>() % 100_000, Ordering::Relaxed);
21+
let tx_bytes_0 = BASE_TX_BYTES_0.fetch_add(rand::random::<u64>() % 80_000, Ordering::Relaxed);
2222
let rx_packets_0 = BASE_RX_PACKETS_0.fetch_add(rand::random::<u64>() % 1000, Ordering::Relaxed);
2323
let tx_packets_0 = BASE_TX_PACKETS_0.fetch_add(rand::random::<u64>() % 900, Ordering::Relaxed);
24-
let rx_errors_0 = BASE_RX_ERRORS_0.fetch_add(
25-
if rand::random::<u8>() % 100 < 5 { 1 } else { 0 },
26-
Ordering::Relaxed,
27-
);
28-
let tx_errors_0 = BASE_TX_ERRORS_0.fetch_add(
29-
if rand::random::<u8>() % 100 < 3 { 1 } else { 0 },
30-
Ordering::Relaxed,
31-
);
24+
let rx_errors_0 =
25+
BASE_RX_ERRORS_0.fetch_add(u64::from(rand::random::<u8>() % 100 < 5), Ordering::Relaxed);
26+
let tx_errors_0 =
27+
BASE_TX_ERRORS_0.fetch_add(u64::from(rand::random::<u8>() % 100 < 3), Ordering::Relaxed);
3228

33-
let rx_bytes_1 = BASE_RX_BYTES_1.fetch_add(rand::random::<u64>() % 150000, Ordering::Relaxed);
34-
let tx_bytes_1 = BASE_TX_BYTES_1.fetch_add(rand::random::<u64>() % 120000, Ordering::Relaxed);
29+
let rx_bytes_1 = BASE_RX_BYTES_1.fetch_add(rand::random::<u64>() % 150_000, Ordering::Relaxed);
30+
let tx_bytes_1 = BASE_TX_BYTES_1.fetch_add(rand::random::<u64>() % 120_000, Ordering::Relaxed);
3531
let rx_packets_1 = BASE_RX_PACKETS_1.fetch_add(rand::random::<u64>() % 1500, Ordering::Relaxed);
3632
let tx_packets_1 = BASE_TX_PACKETS_1.fetch_add(rand::random::<u64>() % 1400, Ordering::Relaxed);
37-
let rx_errors_1 = BASE_RX_ERRORS_1.fetch_add(
38-
if rand::random::<u8>() % 100 < 4 { 1 } else { 0 },
39-
Ordering::Relaxed,
40-
);
41-
let tx_errors_1 = BASE_TX_ERRORS_1.fetch_add(
42-
if rand::random::<u8>() % 100 < 2 { 1 } else { 0 },
43-
Ordering::Relaxed,
44-
);
45-
let rx_dropped_1 = BASE_RX_DROPPED_1.fetch_add(
46-
if rand::random::<u8>() % 100 < 1 { 1 } else { 0 },
47-
Ordering::Relaxed,
48-
);
33+
let rx_errors_1 =
34+
BASE_RX_ERRORS_1.fetch_add(u64::from(rand::random::<u8>() % 100 < 4), Ordering::Relaxed);
35+
let tx_errors_1 =
36+
BASE_TX_ERRORS_1.fetch_add(u64::from(rand::random::<u8>() % 100 < 2), Ordering::Relaxed);
37+
let rx_dropped_1 =
38+
BASE_RX_DROPPED_1.fetch_add(u64::from(rand::random::<u8>() % 100 < 1), Ordering::Relaxed);
4939

5040
vec![
5141
AdapterInfo {

src/discovery/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub(crate) mod fake;
22

3-
use crate::types::*;
3+
use crate::types::{AdapterInfo, PortCounters, PortInfo, PortState};
44

55
const MLX5_DATA_MULTIPLIER: u64 = 4; // mlx5 reports in 32-bit words
66

@@ -15,7 +15,11 @@ pub(crate) fn discover_adapters() -> Vec<AdapterInfo> {
1515
};
1616

1717
for entry in entries.flatten() {
18-
if let Some(adapter_name) = entry.file_name().to_str().map(|s| s.to_string()) {
18+
if let Some(adapter_name) = entry
19+
.file_name()
20+
.to_str()
21+
.map(std::string::ToString::to_string)
22+
{
1923
let adapter = create_adapter_info(adapter_name, &entry.path());
2024
adapters.push(adapter);
2125
}

src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn main() -> Result<(), io::Error> {
3333
terminal.show_cursor()?;
3434

3535
if let Err(err) = res {
36-
println!("{:?}", err);
36+
println!("{err:?}");
3737
}
3838

3939
Ok(())
@@ -76,7 +76,9 @@ fn run_app<B: ratatui::backend::Backend>(terminal: &mut Terminal<B>) -> io::Resu
7676
match key.code {
7777
KeyCode::Char('q') | KeyCode::Esc => return Ok(()),
7878
KeyCode::Char('r') => {
79-
last_metrics_update = Instant::now() - metrics_update_interval;
79+
last_metrics_update = Instant::now()
80+
.checked_sub(metrics_update_interval)
81+
.unwrap_or_else(Instant::now);
8082
}
8183
_ => {}
8284
}

src/metrics.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ impl MetricsCollector {
3838
let now = Instant::now();
3939
let time_delta = self
4040
.last_collection
41-
.map(|last| now.duration_since(last))
42-
.unwrap_or(Duration::from_secs(1));
41+
.map_or(Duration::from_secs(1), |last| now.duration_since(last));
4342

4443
// Track current port keys to clean up stale entries
4544
let mut current_port_keys = std::collections::HashSet::new();
@@ -50,7 +49,7 @@ impl MetricsCollector {
5049
current_port_keys.insert(port_key.clone());
5150

5251
if let Some(prev_counters) = self.previous_counters.get(&port_key) {
53-
let metrics = self.calculate_rates(prev_counters, &port.counters, time_delta);
52+
let metrics = Self::calculate_rates(prev_counters, &port.counters, time_delta);
5453
self.current_metrics.insert(port_key.clone(), metrics);
5554
}
5655

@@ -69,8 +68,8 @@ impl MetricsCollector {
6968
self.last_collection = Some(now);
7069
}
7170

71+
#[allow(clippy::cast_precision_loss)]
7272
fn calculate_rates(
73-
&self,
7473
prev: &PortCounters,
7574
current: &PortCounters,
7675
time_delta: Duration,
@@ -91,7 +90,7 @@ impl MetricsCollector {
9190
}
9291

9392
pub fn get_metrics(&self, adapter_name: &str, port_number: u16) -> Option<&PortMetrics> {
94-
let port_key = format!("{}:{}", adapter_name, port_number);
93+
let port_key = format!("{adapter_name}:{port_number}");
9594
self.current_metrics.get(&port_key)
9695
}
9796
}

src/ui.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn draw_help_footer(frame: &mut Frame, area: Rect) {
2626
let help_text = Paragraph::new("Controls: q=quit").style(Style::default().fg(Color::DarkGray));
2727
frame.render_widget(help_text, area);
2828
}
29-
29+
#[allow(clippy::too_many_lines)]
3030
fn draw_adapters(
3131
frame: &mut Frame,
3232
area: Rect,
@@ -147,16 +147,22 @@ fn draw_adapters(
147147
}
148148

149149
fn format_bytes(bytes: u64) -> String {
150-
const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB"];
151-
let mut value = bytes as f64;
150+
const UNITS: &[&str] = &["B", "KB", "MB", "GB", "TB", "PB"];
151+
let mut value = bytes;
152152
let mut unit_index = 0;
153153

154-
while value >= 1024.0 && unit_index < UNITS.len() - 1 {
155-
value /= 1024.0;
154+
while value >= 1024 && unit_index < UNITS.len() - 1 {
155+
value /= 1024;
156156
unit_index += 1;
157157
}
158158

159-
format!("{:.1}{}", value, UNITS[unit_index])
159+
if unit_index == 0 {
160+
format!("{}{}", value, UNITS[unit_index])
161+
} else {
162+
let fractional = (bytes >> (10 * (unit_index - 1))) % 1024;
163+
let decimal_part = (fractional * 10) / 1024;
164+
format!("{}.{}{}", value, decimal_part, UNITS[unit_index])
165+
}
160166
}
161167

162168
fn format_bytes_per_sec(bytes_per_sec: f64) -> String {
@@ -175,3 +181,34 @@ fn format_bytes_per_sec(bytes_per_sec: f64) -> String {
175181
format!("{:.1}{}", value, UNITS[unit_index])
176182
}
177183
}
184+
185+
#[cfg(test)]
186+
mod tests {
187+
use super::*;
188+
189+
#[test]
190+
fn test_format_bytes() {
191+
assert_eq!(format_bytes(0), "0B");
192+
assert_eq!(format_bytes(1023), "1023B");
193+
assert_eq!(format_bytes(1024), "1.0KB");
194+
assert_eq!(format_bytes(1025), "1.0KB");
195+
assert_eq!(format_bytes(1024 * 1024), "1.0MB");
196+
assert_eq!(format_bytes(1024 * 1024 * 1024), "1.0GB");
197+
assert_eq!(format_bytes(1024 * 1024 * 1024 * 1024), "1.0TB");
198+
assert_eq!(format_bytes(1024 * 1024 * 1024 * 1024 * 1024), "1.0PB");
199+
}
200+
201+
#[test]
202+
fn test_format_bytes_per_sec() {
203+
assert_eq!(format_bytes_per_sec(0.0), "0.00B/s");
204+
assert_eq!(format_bytes_per_sec(1023.0), "1023.0B/s");
205+
assert_eq!(format_bytes_per_sec(1024.0), "1.0KB/s");
206+
assert_eq!(format_bytes_per_sec(1025.0), "1.0KB/s");
207+
assert_eq!(format_bytes_per_sec(1024.0 * 1024.0), "1.0MB/s");
208+
assert_eq!(format_bytes_per_sec(1024.0 * 1024.0 * 1024.0), "1.0GB/s");
209+
assert_eq!(
210+
format_bytes_per_sec(1024.0 * 1024.0 * 1024.0 * 1024.0),
211+
"1.0TB/s"
212+
);
213+
}
214+
}

0 commit comments

Comments
 (0)