1use std::{
2 fmt::Display,
3 sync::{Arc, Weak},
4};
5
6use super::*;
7
8#[derive(Debug, Default, serde::Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct Device {
17 device_id: String,
18 device_name: String,
19 #[serde(default)]
20 device_type: String,
21 #[serde(default)]
22 remote_type: String,
23 hub_device_id: String,
24
25 #[serde(skip)]
26 service: Weak<SwitchBotService>,
27}
28
29impl Device {
30 pub(crate) fn new_for_test(index: usize) -> Self {
31 Self {
32 device_id: format!("device{}", index),
33 device_name: format!("Device {}", index),
34 device_type: "test".into(),
35 ..Default::default()
36 }
37 }
38
39 pub fn device_id(&self) -> &str {
41 &self.device_id
42 }
43
44 pub fn device_name(&self) -> &str {
47 &self.device_name
48 }
49
50 pub fn is_remote(&self) -> bool {
52 !self.remote_type.is_empty()
53 }
54
55 pub fn device_type(&self) -> &str {
58 &self.device_type
59 }
60
61 pub fn remote_type(&self) -> &str {
63 &self.remote_type
64 }
65
66 pub fn hub_device_id(&self) -> &str {
68 &self.hub_device_id
69 }
70
71 fn service(&self) -> anyhow::Result<Arc<SwitchBotService>> {
72 self.service
73 .upgrade()
74 .ok_or_else(|| anyhow::anyhow!("The service is dropped"))
75 }
76
77 pub(crate) fn set_service(&mut self, service: &Arc<SwitchBotService>) {
78 self.service = Arc::downgrade(service);
79 }
80
81 pub async fn command(&self, command: &CommandRequest) -> anyhow::Result<()> {
87 self.service()?.command(self.device_id(), command).await
88 }
89}
90
91impl Display for Device {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 if f.alternate() {
94 writeln!(f, "Name: {}", self.device_name())?;
95 writeln!(f, "ID: {}", self.device_id())?;
96 if self.is_remote() {
97 write!(f, "Remote Type: {}", self.remote_type())?;
98 } else {
99 write!(f, "Type: {}", self.device_type())?;
100 }
101 return Ok(());
102 }
103 write!(
104 f,
105 "{} ({}, ID:{})",
106 self.device_name,
107 if self.is_remote() {
108 self.remote_type()
109 } else {
110 self.device_type()
111 },
112 self.device_id
113 )
114 }
115}