alarm_dot_com/models/
lock.rs1use serde::{Deserialize, Serialize};
4use std::fmt;
5
6use super::device::{Device, ResourceType};
7use super::jsonapi::Resource;
8use crate::error::{AlarmError, Result};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum LockState {
13 Unknown,
14 Locked,
15 Unlocked,
16}
17
18impl LockState {
19 pub fn from_code(code: u32) -> Self {
20 match code {
21 1 => LockState::Locked,
22 2 => LockState::Unlocked,
23 _ => LockState::Unknown,
24 }
25 }
26}
27
28impl fmt::Display for LockState {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 LockState::Unknown => write!(f, "Unknown"),
32 LockState::Locked => write!(f, "Locked"),
33 LockState::Unlocked => write!(f, "Unlocked"),
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum LockCommand {
41 Lock,
42 Unlock,
43}
44
45impl LockCommand {
46 pub fn api_action(&self) -> &'static str {
47 match self {
48 LockCommand::Lock => "lock",
49 LockCommand::Unlock => "unlock",
50 }
51 }
52}
53
54#[derive(Debug, Clone, Deserialize, Serialize)]
56#[serde(rename_all = "camelCase")]
57pub struct LockAttributes {
58 #[serde(default)]
59 pub state: u32,
60 #[serde(default)]
61 pub desired_state: u32,
62 #[serde(default)]
63 pub description: Option<String>,
64 #[serde(default)]
65 pub has_permission: Option<bool>,
66 #[serde(default)]
67 pub low_battery: Option<bool>,
68 #[serde(default)]
69 pub critical_battery: Option<bool>,
70 #[serde(default)]
71 pub malfunction: Option<bool>,
72}
73
74#[derive(Debug, Clone)]
76pub struct Lock {
77 pub id: String,
78 pub name: String,
79 pub state: LockState,
80 pub desired_state: LockState,
81 pub low_battery: bool,
82 pub malfunction: bool,
83 pub attributes: LockAttributes,
84}
85
86impl Lock {
87 pub fn from_resource(resource: &Resource) -> Result<Self> {
88 let attrs: LockAttributes =
89 serde_json::from_value(resource.attributes.clone()).map_err(|e| {
90 AlarmError::UnexpectedResponse(format!("failed to parse lock attributes: {e}"))
91 })?;
92
93 let name = attrs
94 .description
95 .clone()
96 .unwrap_or_else(|| format!("Lock {}", resource.id));
97
98 Ok(Lock {
99 id: resource.id.clone(),
100 name,
101 state: LockState::from_code(attrs.state),
102 desired_state: LockState::from_code(attrs.desired_state),
103 low_battery: attrs.low_battery.unwrap_or(false),
104 malfunction: attrs.malfunction.unwrap_or(false),
105 attributes: attrs,
106 })
107 }
108}
109
110impl Device for Lock {
111 fn id(&self) -> &str {
112 &self.id
113 }
114
115 fn name(&self) -> &str {
116 &self.name
117 }
118
119 fn resource_type() -> ResourceType {
120 ResourceType::Lock
121 }
122}