Skip to main content

unifi/
service.rs

1use serde_json::Value;
2
3use crate::error::Result;
4use crate::util::truncate_data_array;
5use crate::{ActionDispatcher, ActionRequest, UnifiClient};
6
7/// Business-logic facade over [`UnifiClient`]: fixed read endpoints plus
8/// dynamic action dispatch via [`ActionDispatcher`].
9///
10/// Consumers embedding this crate (CLI commands, MCP tools, HTTP handlers)
11/// should depend on `UnifiService`, not [`UnifiClient`] directly — it is the
12/// stable seam for adding cross-cutting behavior (result shaping, caching,
13/// metrics) without touching every call site.
14#[derive(Clone)]
15pub struct UnifiService {
16    client: UnifiClient,
17}
18
19impl UnifiService {
20    /// Wraps an already-built [`UnifiClient`].
21    pub fn new(client: UnifiClient) -> Self {
22        Self { client }
23    }
24
25    /// Connected clients (wireless and wired).
26    ///
27    /// # Errors
28    /// See [`crate::UnifiError`] for the failure cases this can return.
29    pub async fn clients(&self) -> Result<Value> {
30        self.client.clients().await
31    }
32
33    /// Network devices: APs, switches, gateways.
34    ///
35    /// # Errors
36    /// See [`crate::UnifiError`] for the failure cases this can return.
37    pub async fn devices(&self) -> Result<Value> {
38        self.client.devices().await
39    }
40
41    /// WLAN (WiFi network) configurations.
42    ///
43    /// # Errors
44    /// See [`crate::UnifiError`] for the failure cases this can return.
45    pub async fn wlans(&self) -> Result<Value> {
46        self.client.wlans().await
47    }
48
49    /// Site health summary.
50    ///
51    /// # Errors
52    /// See [`crate::UnifiError`] for the failure cases this can return.
53    pub async fn health(&self) -> Result<Value> {
54        self.client.health().await
55    }
56
57    /// Active alarms / alerts.
58    ///
59    /// # Errors
60    /// See [`crate::UnifiError`] for the failure cases this can return.
61    pub async fn alarms(&self) -> Result<Value> {
62        self.client.alarms().await
63    }
64
65    /// Recent events, truncated to `limit` entries when given.
66    ///
67    /// # Errors
68    /// See [`crate::UnifiError`] for the failure cases this can return.
69    pub async fn events(&self, limit: Option<usize>) -> Result<Value> {
70        let mut events = self.client.events().await?;
71        truncate_data_array(&mut events, limit);
72        Ok(events)
73    }
74
75    /// Controller system info.
76    ///
77    /// # Errors
78    /// See [`crate::UnifiError`] for the failure cases this can return.
79    pub async fn sysinfo(&self) -> Result<Value> {
80        self.client.sysinfo().await
81    }
82
83    /// Authenticated user info.
84    ///
85    /// # Errors
86    /// See [`crate::UnifiError`] for the failure cases this can return.
87    pub async fn me(&self) -> Result<Value> {
88        self.client.me().await
89    }
90
91    /// Runs a named, dynamically-dispatched action (see [`ActionDispatcher`]).
92    ///
93    /// # Errors
94    /// See [`crate::UnifiError`] for the failure cases this can return.
95    pub async fn execute(&self, request: ActionRequest) -> Result<Value> {
96        ActionDispatcher::new(self.client.clone())
97            .execute(request)
98            .await
99    }
100}