use crate::resource::{self, light};
use crate::util;
use derive_setters::Setters;
use serde::{Deserialize, Serialize};
use serde_repr::Deserialize_repr;
use std::collections::HashMap;
#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize)]
pub struct Scene {
#[serde(skip_deserializing)]
pub id: String,
pub name: String,
#[serde(rename = "type")]
pub kind: Kind,
pub group: Option<String>,
pub lights: Option<Vec<String>>,
#[serde(deserialize_with = "util::deserialize_option_string")]
pub owner: Option<String>,
pub recycle: bool,
pub locked: bool,
#[serde(rename = "appdata")]
pub app_data: AppData,
pub picture: Option<String>,
#[serde(rename = "lastupdate")]
pub last_update: Option<chrono::NaiveDateTime>,
pub version: Version,
}
impl Scene {
pub(crate) fn with_id(self, id: String) -> Self {
Self { id, ..self }
}
}
impl resource::Resource for Scene {}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Deserialize, Serialize)]
pub enum Kind {
LightScene,
GroupScene,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Deserialize, Serialize)]
pub struct AppData {
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<i8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<String>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Deserialize_repr)]
#[repr(i32)]
pub enum Version {
Put = 1,
Post = 2,
}
#[derive(Clone, Debug, PartialEq, Serialize, Setters)]
#[setters(strip_option, prefix = "with_")]
pub struct Creator {
#[setters(skip)]
pub name: String,
#[setters(skip)]
pub lights: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
pub kind: Option<Kind>,
#[serde(skip_serializing_if = "Option::is_none", rename = "appdata")]
pub app_data: Option<AppData>,
#[serde(skip_serializing_if = "Option::is_none", rename = "lightstates")]
pub light_states: Option<HashMap<String, light::StaticStateModifier>>,
}
impl Creator {
pub fn new(name: String, lights: Vec<String>) -> Self {
Self {
name,
lights,
kind: None,
app_data: None,
light_states: None,
}
}
}
impl resource::Creator for Creator {
fn url_suffix() -> String {
"scenes".to_owned()
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Setters)]
#[setters(strip_option, prefix = "with_")]
pub struct Modifier {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lights: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "lightstates")]
pub light_states: Option<HashMap<String, light::StaticStateModifier>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "storelightstate")]
pub store_light_state: Option<bool>,
}
impl Modifier {
pub fn new() -> Self {
Self::default()
}
}
impl resource::Modifier for Modifier {
type Id = String;
fn url_suffix(id: Self::Id) -> String {
format!("scenes/{}", id)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn serialize_creator() {
let creator = Creator::new("test".into(), vec!["1".into()]);
let creator_json = serde_json::to_value(creator).unwrap();
let expected_json = json!({
"name": "test",
"lights": ["1"]
});
assert_eq!(creator_json, expected_json);
let creator = Creator {
name: "test".into(),
lights: vec!["1".into()],
kind: Some(Kind::GroupScene),
app_data: Some(AppData {
version: Some(2),
data: Some("data test".into()),
}),
light_states: Some(HashMap::new()),
};
let creator_json = serde_json::to_value(creator).unwrap();
let expected_json = json!({
"name": "test",
"lights": ["1"],
"type": "GroupScene",
"appdata": {
"version": 2,
"data": "data test"
},
"lightstates": {}
});
assert_eq!(creator_json, expected_json);
}
#[test]
fn serialize_modifier() {
let modifier = Modifier::new();
let modifier_json = serde_json::to_value(modifier).unwrap();
let expected_json = json!({});
assert_eq!(modifier_json, expected_json);
let modifier = Modifier {
name: Some("test".into()),
lights: Some(vec!["1".into(), "2".into()]),
light_states: Some(HashMap::new()),
store_light_state: Some(true),
};
let modifier_json = serde_json::to_value(modifier).unwrap();
let expected_json = json!({
"name": "test",
"lights": ["1", "2"],
"lightstates": {},
"storelightstate": true
});
assert_eq!(modifier_json, expected_json);
}
}