Skip to main content

kanade_shared/wire/
inventory.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Serialize, Deserialize, Debug, Clone)]
4pub struct HwInventory {
5    pub pc_id: String,
6    pub hostname: String,
7    pub os_name: String,
8    pub os_version: String,
9    pub os_build: Option<String>,
10    pub cpu_model: String,
11    pub cpu_cores: u32,
12    pub ram_bytes: u64,
13    pub disks: Vec<DiskInfo>,
14    pub collected_at: chrono::DateTime<chrono::Utc>,
15}
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
18pub struct DiskInfo {
19    pub device_id: String,
20    pub size_bytes: u64,
21    pub free_bytes: u64,
22    pub file_system: Option<String>,
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28    use chrono::TimeZone;
29
30    #[test]
31    fn hw_inventory_round_trips_with_disks() {
32        let inv = HwInventory {
33            pc_id: "minipc".into(),
34            hostname: "MINIPC".into(),
35            os_name: "Windows 11 Pro".into(),
36            os_version: "10.0.26200".into(),
37            os_build: Some("26200".into()),
38            cpu_model: "Intel Core i7".into(),
39            cpu_cores: 12,
40            ram_bytes: 64 * 1024 * 1024 * 1024,
41            disks: vec![DiskInfo {
42                device_id: "C:".into(),
43                size_bytes: 1_000_000_000_000,
44                free_bytes: 500_000_000_000,
45                file_system: Some("NTFS".into()),
46            }],
47            collected_at: chrono::Utc.with_ymd_and_hms(2026, 5, 16, 0, 0, 0).unwrap(),
48        };
49        let json = serde_json::to_string(&inv).unwrap();
50        let back: HwInventory = serde_json::from_str(&json).unwrap();
51        assert_eq!(back.disks.len(), 1);
52        assert_eq!(back.disks[0].device_id, "C:");
53        assert_eq!(back.cpu_cores, 12);
54        assert_eq!(back.ram_bytes, inv.ram_bytes);
55    }
56}