roowho2_lib/server/varlink_api/
rwhod.rs1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use zlink::ReplyError;
5
6use crate::{
7 proto::{WhodStatusUpdate, WhodUserEntry},
8 server::rwhod::RwhodStatusStore,
9};
10
11#[zlink::proxy("no.ntnu.pvv.roowho2.rwhod")]
12pub trait VarlinkRwhodClientProxy {
13 async fn rwho(
19 &mut self,
20 max_idle_seconds: Option<i64>,
21 ) -> zlink::Result<Result<VarlinkRwhoResponse, VarlinkRwhodClientError>>;
22
23 async fn ruptime(
25 &mut self,
26 max_idle_seconds: Option<i64>,
27 ) -> zlink::Result<Result<VarlinkRuptimeResponse, VarlinkRwhodClientError>>;
28}
29
30#[derive(Debug, Deserialize)]
31#[serde(tag = "method", content = "parameters")]
32pub enum VarlinkRwhodClientRequest {
33 #[serde(rename = "no.ntnu.pvv.roowho2.rwhod.Rwho")]
34 Rwho {
35 max_idle_seconds: Option<i64>,
38 },
39
40 #[serde(rename = "no.ntnu.pvv.roowho2.rwhod.Ruptime")]
41 Ruptime {
42 max_idle_seconds: Option<i64>,
45 },
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize)]
49#[serde(untagged)]
50pub enum VarlinkRwhodClientResponse {
51 Rwho(VarlinkRwhoResponse),
52 Ruptime(VarlinkRuptimeResponse),
53}
54
55pub type VarlinkRwhoResponse = HashMap<String, Vec<WhodUserEntry>>;
56pub type VarlinkRuptimeResponse = Vec<WhodStatusUpdate>;
57
58#[derive(Debug, Clone, PartialEq, ReplyError)]
59#[zlink(interface = "no.ntnu.pvv.roowho2.rwhod")]
60pub enum VarlinkRwhodClientError {
61 InvalidRequest,
62 TimedOut,
63 Disabled,
64}
65
66pub async fn handle_rwho_request(
67 whod_status_store: &RwhodStatusStore,
68 max_idle_time: Option<chrono::TimeDelta>,
69) -> VarlinkRwhoResponse {
70 tracing::debug!(?max_idle_time, "Handling Rwho request");
71 let store = whod_status_store.read().await;
72
73 store
74 .values()
75 .filter_map(|status_update| {
76 let users: Vec<WhodUserEntry> = status_update
77 .users
78 .iter()
79 .filter(|user| max_idle_time.is_none_or(|max| user.idle_time < max))
80 .cloned()
81 .collect();
82
83 (!users.is_empty()).then(|| (status_update.hostname.clone(), users))
84 })
85 .collect()
86}
87
88pub async fn handle_ruptime_request(
89 whod_status_store: &RwhodStatusStore,
90 max_idle_time: Option<chrono::TimeDelta>,
91) -> VarlinkRuptimeResponse {
92 tracing::debug!(?max_idle_time, "Handling Ruptime request");
93 let store = whod_status_store.read().await;
94
95 store
96 .values()
97 .cloned()
98 .map(|mut status_update| {
99 if let Some(max_idle_time) = max_idle_time {
100 status_update
101 .users
102 .retain(|user| user.idle_time < max_idle_time);
103 }
104 status_update
105 })
106 .collect()
107}