use std::net::IpAddr;
use chrono::serde::ts_seconds;
use chrono::DateTime;
use chrono::Utc;
use compact_str::CompactString;
use macaddr::MacAddr6;
use serde::Deserialize;
use serde_with::serde_as;
use serde_with::DisplayFromStr;
#[serde_as]
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
pub struct Home {
#[serde(with = "ts_seconds")]
pub software_build_epoch: DateTime<Utc>,
pub is_nonvoy: bool,
pub db_size: CompactString,
#[serde_as(as = "DisplayFromStr")]
pub db_percent_full: u8,
pub timezone: CompactString,
pub current_date: CompactString,
pub current_time: CompactString,
pub network: Network,
pub tariff: CompactString,
pub update_status: CompactString
}
#[serde_as]
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
pub struct Network {
pub web_comm: bool,
pub ever_reported_to_enlighten: bool,
#[serde(with = "ts_seconds")]
pub last_enlighten_report_time: DateTime<Utc>,
pub primary_interface: CompactString,
pub interfaces: Vec<Interface>
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
#[serde(tag = "type")]
pub enum Interface {
#[serde(rename = "ethernet")]
Wired(WiredInterface),
#[serde(rename = "wifi")]
WiFi(WiFiInterface)
}
#[serde_as]
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
pub struct WiredInterface {
pub interface: CompactString,
#[serde_as(as = "DisplayFromStr")]
pub mac: MacAddr6,
pub dhcp: bool,
pub ip: IpAddr,
pub carrier: bool
}
#[serde_as]
#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
pub struct WiFiInterface {
pub interface: CompactString,
pub signal_strength: u8,
pub signal_strength_max: u8,
#[serde_as(as = "DisplayFromStr")]
pub mac: MacAddr6,
pub dhcp: bool,
pub ip: IpAddr,
pub carrier: bool,
pub supported: bool,
pub present: bool,
pub configured: bool,
pub status: CompactString
}
#[cfg(test)]
mod tests {
use chrono::TimeZone;
use super::*;
#[test]
fn test_deserialize_home() {
let s = include_str!("home/testdata/home.json");
let home: Home = serde_json::from_str(s).unwrap();
assert_eq!(
home,
Home {
software_build_epoch: Utc.timestamp_opt(1584607493, 0).unwrap(),
is_nonvoy: false,
db_size: "43 MB".into(),
db_percent_full: 11,
timezone: "US/Eastern".into(),
current_date: "12/12/2022".into(),
current_time: "14:36".into(),
network: Network {
web_comm: true,
ever_reported_to_enlighten: true,
last_enlighten_report_time: Utc.timestamp_opt(1670873269, 0).unwrap(),
primary_interface: "none".into(),
interfaces: vec![
Interface::Wired(WiredInterface {
interface: "eth0".into(),
mac: MacAddr6::new(0x00, 0x1d, 0xc0, 0x6d, 0x32, 0xc6),
dhcp: true,
ip: IpAddr::from([169, 254, 120, 1]),
carrier: false
}),
Interface::WiFi(WiFiInterface {
interface: "wlan0".into(),
signal_strength: 3,
signal_strength_max: 5,
mac: MacAddr6::new(0x38, 0x81, 0xd7, 0x35, 0x9b, 0xd2),
dhcp: true,
ip: IpAddr::from([192, 168, 1, 80]),
carrier: true,
supported: true,
present: true,
configured: true,
status: "connected".into()
})
]
},
tariff: "none".into(),
update_status: "satisfied".into()
}
);
}
}