1use serde::{Deserialize, Serialize};
2
3pub mod contracts;
4pub mod settings;
5pub mod status;
6
7pub const V1: &str = "v1";
8pub const STATUS_CONTRACT: &str = "mhome.node.status.v1";
9pub const PROTOCOL_V1_MANIFEST: &str = include_str!("../../contract/node-runtime-protocol-v1.json");
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase", deny_unknown_fields)]
13pub struct RuntimeRequest<T> {
14 pub version: String,
15 pub payload: T,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct RuntimeResponse<T> {
21 pub version: String,
22 pub data: T,
23}
24
25pub fn require_version(actual: &str, expected: &str) -> Result<(), UnsupportedVersion> {
26 if actual == expected {
27 Ok(())
28 } else {
29 Err(UnsupportedVersion {
30 actual: actual.to_string(),
31 expected: expected.to_string(),
32 })
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct UnsupportedVersion {
38 actual: String,
39 expected: String,
40}
41
42impl std::fmt::Display for UnsupportedVersion {
43 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 write!(
45 formatter,
46 "UNSUPPORTED_NODE_PROTOCOL_VERSION: requested version {}, supported version {}",
47 self.actual, self.expected
48 )
49 }
50}
51
52impl std::error::Error for UnsupportedVersion {}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn manifest_matches_internal_targets() {
60 let manifest: serde_json::Value = serde_json::from_str(PROTOCOL_V1_MANIFEST).unwrap();
61 assert_eq!(manifest["version"], V1);
62 assert_eq!(manifest["status"]["contract"], STATUS_CONTRACT);
63 assert_eq!(manifest["status"]["queryTarget"], status::STATUS_TARGET);
64 assert_eq!(
65 manifest["status"]["changedTarget"],
66 status::STATUS_CHANGED_TARGET
67 );
68 assert_eq!(
69 manifest["settings"]["changedTarget"],
70 settings::CHANGED_TARGET
71 );
72 assert_eq!(
73 manifest["llm"]["completeTarget"],
74 crate::llm::COMPLETE_TARGET
75 );
76 assert_eq!(
77 manifest["llm"]["ttsSynthesizeTarget"],
78 contracts::llm::TTS_SYNTHESIZE_TARGET
79 );
80 }
81}