use std::fmt;
use busylib::model::settings::{AccessMode, HttpAccessInfo};
use busylib::types::brightness::Brightness;
use busylib::types::device_name::DeviceName;
use busylib::types::volume::Volume;
use serde::Serialize;
use crate::reporter::events::CliEvent;
use crate::reporter::events::fields::{field, write_fields};
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SettingsAccessEvent(HttpAccessInfo);
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SettingsNameEvent {
name: DeviceName,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SettingsVolumeEvent {
volume: Volume,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SettingsBrightnessEvent {
value: Brightness,
}
impl SettingsAccessEvent {
pub fn new(access: HttpAccessInfo) -> Self {
Self(access)
}
}
impl SettingsNameEvent {
pub fn new(name: DeviceName) -> Self {
Self { name }
}
}
impl SettingsVolumeEvent {
pub fn new(volume: Volume) -> Self {
Self { volume }
}
}
impl SettingsBrightnessEvent {
pub fn new(value: Brightness) -> Self {
Self { value }
}
}
impl From<SettingsAccessEvent> for CliEvent {
fn from(event: SettingsAccessEvent) -> Self {
CliEvent::SettingsAccess(event)
}
}
impl From<SettingsNameEvent> for CliEvent {
fn from(event: SettingsNameEvent) -> Self {
CliEvent::SettingsName(event)
}
}
impl From<SettingsVolumeEvent> for CliEvent {
fn from(event: SettingsVolumeEvent) -> Self {
CliEvent::SettingsVolume(event)
}
}
impl From<SettingsBrightnessEvent> for CliEvent {
fn from(event: SettingsBrightnessEvent) -> Self {
CliEvent::SettingsBrightness(event)
}
}
impl fmt::Display for SettingsAccessEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let access = &self.0;
let mut fields = vec![field("mode", access_mode_label(access.mode))];
if let Some(key_valid) = access.key_valid {
fields.push(field("key valid", key_valid));
}
write_fields(f, &fields)
}
}
impl fmt::Display for SettingsNameEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.name.as_str())
}
}
impl fmt::Display for SettingsVolumeEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}%", self.volume.percent())
}
}
impl fmt::Display for SettingsBrightnessEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.value)
}
}
fn access_mode_label(mode: AccessMode) -> &'static str {
match mode {
AccessMode::Disabled => "disabled",
AccessMode::Enabled => "enabled",
AccessMode::Key => "key",
}
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
fn renders_the_access_configuration() {
let event = SettingsAccessEvent::new(HttpAccessInfo {
mode: AccessMode::Key,
key_valid: Some(true),
});
assert_eq!(event.to_string(), "mode: key\nkey valid: true");
assert_eq!(
serde_json::to_value(CliEvent::from(event)).unwrap(),
json!({"event": "settings_access", "mode": "key", "key_valid": true})
);
}
#[test]
fn renders_single_value_settings_bare() {
assert_eq!(
SettingsNameEvent::new(DeviceName::new("BUSY Bar").unwrap()).to_string(),
"BUSY Bar"
);
assert_eq!(
SettingsVolumeEvent::new(Volume::new(35).unwrap()).to_string(),
"35%"
);
assert_eq!(
SettingsBrightnessEvent::new(Brightness::Auto).to_string(),
"auto"
);
assert_eq!(
SettingsBrightnessEvent::new(Brightness::level(40).unwrap()).to_string(),
"40"
);
}
}