Skip to main content

cli_speedtest/
models.rs

1// src/models.rs
2
3use serde::Serialize;
4
5/// Shared config object - replaces quiet: bool prop-drilling
6#[derive(Debug, Clone)]
7pub struct AppConfig {
8    pub quiet: bool,
9    pub color: bool,
10}
11
12/// All parameters the core `run()` function needs, decoupled from clap's `Args`.
13/// This is what allows integration tests to call `run()` without constructing CLI args.
14#[derive(Debug, Clone)]
15pub struct RunArgs {
16    pub server_url: String,
17    pub duration_secs: u64,
18    pub connections: Option<usize>,
19    pub ping_count: u32,
20    pub no_download: bool,
21    pub no_upload: bool,
22}
23
24#[derive(Serialize, Debug, Clone)]
25pub struct PingStats {
26    pub min_ms: u128,
27    pub max_ms: u128,
28    pub avg_ms: f64,
29    pub jitter_ms: f64,
30    pub packet_loss_pct: f64,
31}
32
33#[derive(Serialize, Debug, Clone)]
34pub struct SpeedTestResult {
35    pub timestamp: String,
36    pub version: String,
37    pub server_name: String,
38    pub ping: PingStats,
39    // CHANGED: Option<f64> so skipped tests serialize as null / are absent
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub download_mbps: Option<f64>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub upload_mbps: Option<f64>,
44}
45
46#[derive(Debug, Clone)]
47pub struct Server {
48    pub name: String,
49    pub base_url: String,
50}
51
52/// Interactive menu settings state
53#[derive(Debug, Clone)]
54pub struct MenuSettings {
55    pub duration_secs: u64, // default: 10
56    pub connections: usize, // default: 4
57    pub ping_count: u32,    // default: 20
58    pub color: bool,        // default: true
59}
60
61impl Default for MenuSettings {
62    fn default() -> Self {
63        Self {
64            duration_secs: 10,
65            connections: 4,
66            ping_count: 20,
67            color: true,
68        }
69    }
70}