Skip to main content

huawei_dongle_api/api/
device.rs

1//! Device API endpoints
2
3use crate::{
4    client::Client,
5    error::{Error, Result},
6    models::{common::Response, device::*},
7};
8use tracing::{debug, trace};
9
10/// Device API for device information and control operations
11pub 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}