huawei_dongle_api/api/
device.rs1use crate::{
4 client::Client,
5 error::{Error, Result},
6 models::{common::Response, device::*},
7};
8use tracing::{debug, trace};
9
10pub struct DeviceApi<'a> {
12 client: &'a Client,
13}
14
15impl<'a> DeviceApi<'a> {
16 pub fn new(client: &'a Client) -> Self {
17 Self { client }
18 }
19
20 pub async fn information(&self) -> Result<DeviceInformation> {
21 debug!("Fetching device information");
22
23 let response = self.client.get("/api/device/information").await?;
24 let text = response.text().await?;
25
26 trace!("Device information response: {}", text);
27
28 self.client.check_xml_for_errors(&text).await?;
29
30 let device_info: DeviceInformation = serde_xml_rs::from_str(&text)
31 .map_err(|e| Error::generic(format!("Failed to parse device information: {e}")))?;
32
33 Ok(device_info)
34 }
35
36 pub async fn reboot(&self) -> Result<()> {
37 debug!("Rebooting device");
38
39 let request = DeviceControlRequest::reboot();
40 let xml = serde_xml_rs::to_string(&request)
41 .map_err(|e| Error::generic(format!("Failed to serialize reboot request: {e}")))?;
42
43 let response = self.client.post_xml("/api/device/control", &xml).await?;
44 let text = response.text().await?;
45
46 trace!("Device reboot response: {}", text);
47
48 self.client.check_xml_for_errors(&text).await?;
49
50 let result: Response = serde_xml_rs::from_str(&text)
51 .map_err(|e| Error::generic(format!("Failed to parse reboot response: {e}")))?;
52
53 if !result.is_success() {
54 return Err(Error::api(
55 result.error_code().unwrap_or(-1),
56 result
57 .error_message()
58 .unwrap_or("Device reboot failed")
59 .to_string(),
60 ));
61 }
62
63 debug!("Device reboot initiated successfully");
64 Ok(())
65 }
66
67 pub async fn power_off(&self) -> Result<()> {
68 debug!("Powering off device");
69
70 let request = DeviceControlRequest::power_off();
71 let xml = serde_xml_rs::to_string(&request)
72 .map_err(|e| Error::generic(format!("Failed to serialize power off request: {e}")))?;
73
74 let response = self.client.post_xml("/api/device/control", &xml).await?;
75 let text = response.text().await?;
76
77 trace!("Device power off response: {}", text);
78
79 self.client.check_xml_for_errors(&text).await?;
80
81 let result: Response = serde_xml_rs::from_str(&text)
82 .map_err(|e| Error::generic(format!("Failed to parse power off response: {e}")))?;
83
84 if !result.is_success() {
85 return Err(Error::api(
86 result.error_code().unwrap_or(-1),
87 result
88 .error_message()
89 .unwrap_or("Device power off failed")
90 .to_string(),
91 ));
92 }
93
94 debug!("Device power off initiated successfully");
95 Ok(())
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[tokio::test]
104 async fn test_device_control_serialization() {
105 let reboot_request = DeviceControlRequest::reboot();
106 let xml = serde_xml_rs::to_string(&reboot_request).unwrap();
107
108 assert!(xml.contains("<Control>1</Control>"));
109
110 let power_off_request = DeviceControlRequest::power_off();
111 let xml = serde_xml_rs::to_string(&power_off_request).unwrap();
112
113 assert!(xml.contains("<Control>4</Control>"));
114 }
115}