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}