greentic_types/
runtime_dispatch.rs1use alloc::{format, string::String, vec::Vec};
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
16pub enum DispatchMode {
17 Await,
19 FireAndForget,
21}
22
23#[derive(Clone, Debug, PartialEq)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub struct RuntimeDispatchRequest {
27 pub target: String,
29 pub operation: String,
31 pub mode: DispatchMode,
33 pub input: Value,
35 pub deadline_ms: Option<u64>,
37}
38
39#[derive(Clone, Debug, PartialEq)]
42#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
43pub struct RuntimeDispatchResponse {
44 pub ok: bool,
46 pub output: Value,
48 #[cfg_attr(feature = "serde", serde(default))]
50 pub events: Vec<Value>,
51 #[cfg_attr(
53 feature = "serde",
54 serde(default, skip_serializing_if = "Option::is_none")
55 )]
56 pub error: Option<DispatchError>,
57}
58
59#[derive(Clone, Debug, PartialEq)]
61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
62pub struct DispatchError {
63 pub code: String,
65 pub message: String,
67}
68
69pub fn request_topic(runtime: &str) -> String {
71 format!("greentic.{runtime}.request.v1")
72}
73
74pub fn response_topic(runtime: &str) -> String {
76 format!("greentic.{runtime}.response.v1")
77}
78
79#[cfg(all(test, feature = "serde"))]
80#[allow(clippy::unwrap_used, clippy::expect_used)]
81mod tests {
82 use super::*;
83 use serde_json::json;
84
85 #[test]
86 fn request_round_trips_through_json() {
87 let req = RuntimeDispatchRequest {
88 target: "dep-123".into(),
89 operation: "create_invoice".into(),
90 mode: DispatchMode::Await,
91 input: json!({ "amount": 10 }),
92 deadline_ms: Some(30_000),
93 };
94 let encoded = serde_json::to_value(&req).unwrap();
95 let decoded: RuntimeDispatchRequest = serde_json::from_value(encoded).unwrap();
96 assert_eq!(decoded, req);
97 }
98
99 #[test]
100 fn topic_helpers_use_runtime_name() {
101 assert_eq!(request_topic("sorla"), "greentic.sorla.request.v1");
102 assert_eq!(response_topic("sorla"), "greentic.sorla.response.v1");
103 }
104}