Skip to main content

allora_runtime/spec/
http_outbound_adapter_spec.rs

1use serde::Deserialize;
2
3#[derive(Debug, Clone, Deserialize)]
4pub struct HttpOutboundAdapterSpecRootV1 {
5    pub version: u32,
6    #[serde(rename = "http-outbound-adapter")]
7    pub http_outbound_adapter: HttpOutboundAdapterSpecBlock,
8}
9
10#[derive(Debug, Clone, Deserialize)]
11pub struct HttpOutboundAdapterSpecBlock {
12    pub id: Option<String>,
13    pub host: String,
14    pub port: u16,
15    #[serde(rename = "base-path")]
16    pub base_path: Option<String>,
17    pub path: Option<String>,
18    pub method: Option<String>,
19    #[serde(rename = "use-out-msg")]
20    pub use_out_msg: Option<bool>,
21    /// Channel-driven dispatch: when present, the runtime subscribes this
22    /// adapter to the named inbound channel and dispatches each arriving
23    /// exchange. When absent, the adapter is built but not auto-wired —
24    /// application code can still invoke `.dispatch(&exchange)` directly
25    /// (the legacy http-outbound example pattern).
26    pub from: Option<String>,
27    /// Outbound channel for the post-dispatch exchange. Ignored when
28    /// `from` is absent. When `from` is set but `to` is `None`, the
29    /// adapter is fire-and-forget: dispatch happens, the result is
30    /// logged, the message is dropped.
31    pub to: Option<String>,
32}
33
34#[derive(Debug, Clone)]
35pub struct HttpOutboundAdapterSpec(HttpOutboundAdapterSpecBlock);
36
37impl HttpOutboundAdapterSpec {
38    pub(crate) fn from_block(b: HttpOutboundAdapterSpecBlock) -> Self {
39        Self(b)
40    }
41    pub fn new(
42        host: &str,
43        port: u16,
44        base_path: &str,
45        path: Option<&str>,
46        method: Option<&str>,
47        id: Option<&str>,
48        use_out_msg: bool,
49    ) -> Self {
50        let blk = HttpOutboundAdapterSpecBlock {
51            id: id.map(|s| s.to_string()),
52            host: host.to_string(),
53            port,
54            base_path: Some(base_path.to_string()),
55            path: path.map(|p| p.to_string()),
56            method: method.map(|m| m.to_string()),
57            use_out_msg: Some(use_out_msg),
58            from: None,
59            to: None,
60        };
61        Self(blk)
62    }
63    /// Set the inbound channel name the runtime will subscribe this
64    /// adapter to. Returns `self` for chaining; intended for fluent test
65    /// fixture construction.
66    pub fn with_from(mut self, from: impl Into<String>) -> Self {
67        self.0.from = Some(from.into());
68        self
69    }
70    /// Set the outbound channel name for the post-dispatch exchange.
71    pub fn with_to(mut self, to: impl Into<String>) -> Self {
72        self.0.to = Some(to.into());
73        self
74    }
75    pub fn with_id(
76        id: &str,
77        host: &str,
78        port: u16,
79        base_path: &str,
80        path: Option<&str>,
81        method: Option<&str>,
82        use_out_msg: bool,
83    ) -> Self {
84        Self::new(host, port, base_path, path, method, Some(id), use_out_msg)
85    }
86    pub fn id(&self) -> Option<&str> {
87        self.0.id.as_deref()
88    }
89    pub fn host(&self) -> &str {
90        &self.0.host
91    }
92    pub fn port(&self) -> u16 {
93        self.0.port
94    }
95    pub fn base_path(&self) -> &str {
96        self.0.base_path.as_deref().unwrap_or("/")
97    }
98    pub fn path(&self) -> Option<&str> {
99        self.0.path.as_deref()
100    }
101    pub fn method(&self) -> Option<&str> {
102        self.0.method.as_deref()
103    }
104    pub fn use_out_msg(&self) -> bool {
105        self.0.use_out_msg.unwrap_or(true)
106    }
107    /// Inbound channel name for channel-driven dispatch, if set.
108    pub fn from(&self) -> Option<&str> {
109        self.0.from.as_deref()
110    }
111    /// Outbound channel name for the post-dispatch exchange, if set.
112    pub fn to(&self) -> Option<&str> {
113        self.0.to.as_deref()
114    }
115}