use serde::Deserialize;
use crate::error::ParseError;
use crate::types::PowerState;
#[derive(Debug, Clone, Deserialize)]
pub struct DimmerResponse {
#[serde(rename = "Dimmer")]
dimmer: u8,
#[serde(rename = "POWER", default)]
power: Option<String>,
}
impl DimmerResponse {
#[must_use]
pub fn dimmer(&self) -> u8 {
self.dimmer
}
pub fn power_state(&self) -> Result<Option<PowerState>, ParseError> {
match &self.power {
Some(s) => s
.parse::<PowerState>()
.map(Some)
.map_err(|_| ParseError::InvalidValue {
field: "POWER".to_string(),
message: format!("invalid power state: {s}"),
}),
None => Ok(None),
}
}
#[must_use]
pub fn is_on(&self) -> Option<bool> {
self.power.as_ref().map(|s| s == "ON")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_dimmer_only() {
let json = r#"{"Dimmer": 50}"#;
let response: DimmerResponse = serde_json::from_str(json).unwrap();
assert_eq!(response.dimmer(), 50);
assert!(response.power_state().unwrap().is_none());
assert!(response.is_on().is_none());
}
#[test]
fn parse_dimmer_with_power_on() {
let json = r#"{"Dimmer": 75, "POWER": "ON"}"#;
let response: DimmerResponse = serde_json::from_str(json).unwrap();
assert_eq!(response.dimmer(), 75);
assert_eq!(response.power_state().unwrap().unwrap(), PowerState::On);
assert_eq!(response.is_on(), Some(true));
}
#[test]
fn parse_dimmer_with_power_off() {
let json = r#"{"Dimmer": 0, "POWER": "OFF"}"#;
let response: DimmerResponse = serde_json::from_str(json).unwrap();
assert_eq!(response.dimmer(), 0);
assert_eq!(response.power_state().unwrap().unwrap(), PowerState::Off);
assert_eq!(response.is_on(), Some(false));
}
#[test]
fn parse_dimmer_min_max() {
let json_min = r#"{"Dimmer": 0}"#;
let json_max = r#"{"Dimmer": 100}"#;
let response_min: DimmerResponse = serde_json::from_str(json_min).unwrap();
let response_max: DimmerResponse = serde_json::from_str(json_max).unwrap();
assert_eq!(response_min.dimmer(), 0);
assert_eq!(response_max.dimmer(), 100);
}
#[test]
fn parse_dimmer_with_additional_fields() {
let json = r#"{
"Dimmer": 75,
"POWER": "ON",
"Color": "FFFFFF",
"HSBColor": "0,0,75",
"White": 75,
"CT": 327
}"#;
let response: DimmerResponse = serde_json::from_str(json).unwrap();
assert_eq!(response.dimmer(), 75);
assert_eq!(response.power_state().unwrap().unwrap(), PowerState::On);
}
}