use std::collections::BTreeMap;
use std::path::PathBuf;
use serde::Serialize;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum PdoType {
FixedSupply,
Battery,
VariableSupply,
Pps,
#[default]
Unknown,
}
impl PdoType {
pub fn label(self) -> &'static str {
match self {
PdoType::FixedSupply => "Fixed",
PdoType::Battery => "Battery",
PdoType::VariableSupply => "Variable",
PdoType::Pps => "PPS",
PdoType::Unknown => "Unknown",
}
}
}
#[derive(Debug, Clone, Default, Serialize, PartialEq, Eq)]
pub struct PowerDataObject {
pub r#type: PdoType,
pub voltage_mv: u32,
pub max_voltage_mv: u32,
pub current_ma: u32,
pub power_mw: u32,
pub is_active: bool,
pub index: u32,
}
impl PowerDataObject {
pub fn voltage_label(&self) -> String {
if matches!(self.r#type, PdoType::Pps) && self.max_voltage_mv > 0 {
format!(
"{:.1}-{:.1}V",
self.voltage_mv as f64 / 1000.0,
self.max_voltage_mv as f64 / 1000.0
)
} else {
format!("{:.1}V", self.voltage_mv as f64 / 1000.0)
}
}
pub fn current_label(&self) -> String {
format!("{:.2}A", self.current_ma as f64 / 1000.0)
}
pub fn power_label(&self) -> String {
format!("{:.0}W", self.power_mw as f64 / 1000.0)
}
}
#[derive(Debug, Clone, Default, Serialize, PartialEq, Eq)]
pub struct PowerDeliveryPort {
pub sysfs_path: PathBuf,
pub name: String,
pub parent_port_type: String,
pub parent_port_number: i32,
pub source_capabilities: Vec<PowerDataObject>,
pub sink_capabilities: Vec<PowerDataObject>,
pub max_source_power_mw: u32,
pub active_source_pdo_index: Option<u32>,
pub raw_attributes: BTreeMap<String, String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn voltage_label_pps_range() {
let pdo = PowerDataObject {
r#type: PdoType::Pps,
voltage_mv: 3300,
max_voltage_mv: 21000,
..Default::default()
};
assert_eq!(pdo.voltage_label(), "3.3-21.0V");
}
#[test]
fn voltage_label_fixed() {
let pdo = PowerDataObject {
r#type: PdoType::FixedSupply,
voltage_mv: 9000,
..Default::default()
};
assert_eq!(pdo.voltage_label(), "9.0V");
}
#[test]
fn current_and_power_labels() {
let pdo = PowerDataObject {
current_ma: 3000,
power_mw: 60_000,
..Default::default()
};
assert_eq!(pdo.current_label(), "3.00A");
assert_eq!(pdo.power_label(), "60W");
}
#[test]
fn pdo_type_labels() {
assert_eq!(PdoType::FixedSupply.label(), "Fixed");
assert_eq!(PdoType::Pps.label(), "PPS");
assert_eq!(PdoType::Unknown.label(), "Unknown");
}
}