app_facade_api/
runtime.rs1use serde::{Deserialize, Serialize};
2
3pub const STATUS_CONTRACT: &str = "mhome.runtime.status.v1";
4pub const STATUS_LIST_TARGET: &str = "/app/runtime/status/list";
5pub const STATUS_CHANGED_TARGET: &str = "/app/runtime/status/changed";
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
8#[serde(rename_all = "camelCase")]
9pub enum StatusResourceType {
10 NodeInstance,
11 NodeRuntime,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
15#[serde(rename_all = "camelCase")]
16pub struct StatusResource {
17 pub r#type: StatusResourceType,
18 pub id: String,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
22#[serde(rename_all = "camelCase")]
23pub struct StatusPayload {
24 pub contract: String,
25 pub scope_id: String,
26 pub hub_generation: String,
27 pub hub_revision: u64,
28 pub observed_at_ms: i64,
29 pub resource: StatusResource,
30 pub deleted: bool,
31 #[serde(default)]
32 pub snapshot: Option<serde_json::Value>,
33}
34
35#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
38#[serde(rename_all = "camelCase", deny_unknown_fields)]
39pub struct StatusListRequest {
40 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub resource_type: Option<StatusResourceType>,
42 #[serde(default, skip_serializing_if = "Option::is_none")]
43 pub resource_id: Option<String>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
47#[serde(rename_all = "camelCase")]
48pub struct StatusListResponse {
49 pub contract: String,
50 pub scope_id: String,
51 pub hub_generation: String,
52 #[serde(default)]
53 pub resources: Vec<StatusPayload>,
54 pub observed_at_ms: i64,
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn public_runtime_resources_are_only_hub_normalized_node_state() {
63 assert_eq!(
64 serde_json::to_value(StatusResourceType::NodeInstance).unwrap(),
65 "nodeInstance"
66 );
67 assert_eq!(
68 serde_json::to_value(StatusResourceType::NodeRuntime).unwrap(),
69 "nodeRuntime"
70 );
71 assert!(serde_json::from_str::<StatusResourceType>("\"hubConnection\"").is_err());
72 assert!(serde_json::from_str::<StatusResourceType>("\"managedService\"").is_err());
73 }
74
75 #[test]
76 fn empty_status_list_request_has_no_filters() {
77 let request: StatusListRequest = serde_json::from_str("{}").unwrap();
78 assert_eq!(request, StatusListRequest::default());
79 assert_eq!(serde_json::to_string(&request).unwrap(), "{}");
80 }
81}