core_api/node/contracts/
audiobridge.rs1use serde::{Deserialize, Serialize};
2
3pub const VERSION: &str = crate::node::V1;
4pub const NODE_TYPE: &str = "audiobridge";
5pub const RUNTIME_TARGET_PREFIX: &str = "/audiobridge/app/";
6pub const DEVICE_SNAPSHOT: &str = "device/snapshot";
7pub const DEVICE_REFRESH: &str = "device/refresh";
8pub const DEVICE_PAIR: &str = "device/pair";
9pub const DEVICE_UNPAIR: &str = "device/unpair";
10pub const DEVICE_TEST: &str = "device/test";
11
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase", deny_unknown_fields)]
14pub struct EmptyRequest {}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase", deny_unknown_fields)]
18pub struct DeviceRequest {
19 pub device_id: String,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
23#[serde(rename_all = "camelCase")]
24pub struct AudioBridgeDevice {
25 pub device_id: String,
26 pub display_name: String,
27 pub transport: String,
28 pub online: bool,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
32#[serde(rename_all = "camelCase")]
33pub struct AudioBridgeCandidate {
34 pub device_id: String,
35 pub display_name: String,
36 pub transport: String,
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40#[serde(rename_all = "camelCase")]
41pub struct DeviceSnapshot {
42 #[serde(default)]
43 pub devices: Vec<AudioBridgeDevice>,
44 #[serde(default)]
45 pub candidates: Vec<AudioBridgeCandidate>,
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
49#[serde(rename_all = "camelCase")]
50pub struct PairingResponse {
51 pub changed: bool,
52 pub device: AudioBridgeDevice,
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn public_contract_does_not_expose_platform_identity() {
61 let value = serde_json::to_value(AudioBridgeDevice {
62 device_id: "device-1".to_string(),
63 display_name: "Living Room Speaker".to_string(),
64 transport: "bluetooth".to_string(),
65 online: true,
66 })
67 .expect("serialize device");
68 assert!(value.get("platformKey").is_none());
69 assert!(value.get("endpointId").is_none());
70 }
71
72 #[test]
73 fn device_snapshot_is_the_direct_response_payload() {
74 let value = serde_json::to_value(DeviceSnapshot {
75 devices: Vec::new(),
76 candidates: Vec::new(),
77 })
78 .expect("serialize device snapshot");
79 assert!(value.get("devices").is_some());
80 assert!(value.get("candidates").is_some());
81 assert!(value.get("snapshot").is_none());
82 }
83}