Skip to main content

koi_common/
capability.rs

1use serde::Serialize;
2use utoipa::ToSchema;
3
4/// Summary of a capability's current state for the unified dashboard.
5#[derive(Debug, Clone, Serialize, ToSchema)]
6pub struct CapabilityStatus {
7    pub name: String,
8    pub summary: String,
9    pub healthy: bool,
10}
11
12/// Trait implemented by each domain to participate in `koi status`.
13///
14/// `status` is async so cores can read their internal `tokio` locks directly (the runtime
15/// adapter needs this; the others read sync locks but stay uniform). `name` is sync.
16#[async_trait::async_trait]
17pub trait Capability: Send + Sync {
18    fn name(&self) -> &str;
19    async fn status(&self) -> CapabilityStatus;
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25
26    #[test]
27    fn capability_status_serializes_expected_fields() {
28        let cs = CapabilityStatus {
29            name: "mdns".to_string(),
30            summary: "3 registered".to_string(),
31            healthy: true,
32        };
33        let json = serde_json::to_value(&cs).unwrap();
34        assert_eq!(json.get("name").unwrap(), "mdns");
35        assert_eq!(json.get("summary").unwrap(), "3 registered");
36        assert_eq!(json.get("healthy").unwrap(), true);
37    }
38
39    #[test]
40    fn capability_status_is_send_sync() {
41        fn assert_send_sync<T: Send + Sync>() {}
42        assert_send_sync::<CapabilityStatus>();
43    }
44}