allora_runtime/spec/
http_outbound_adapter_spec_yaml.rs1use crate::error::{Error, Result};
2use crate::spec::http_outbound_adapter_spec::{
3 HttpOutboundAdapterSpec, HttpOutboundAdapterSpecRootV1,
4};
5use serde_yaml::{self, Value as YamlValue};
6
7pub struct HttpOutboundAdapterSpecYamlParser;
8impl HttpOutboundAdapterSpecYamlParser {
9 pub fn parse_value(yaml: &YamlValue) -> Result<HttpOutboundAdapterSpec> {
10 let version_val = yaml
11 .get("version")
12 .and_then(|v| v.as_u64())
13 .ok_or_else(|| Error::serialization("missing or invalid version"))?
14 as u32;
15 if version_val != 1 {
16 return Err(Error::serialization(format!(
17 "unsupported version {} (expected 1)",
18 version_val
19 )));
20 }
21 let root = yaml
22 .get("http-outbound-adapter")
23 .ok_or_else(|| Error::serialization("missing 'http-outbound-adapter'"))?;
24 if !root.is_mapping() {
25 return Err(Error::serialization(
26 "'http-outbound-adapter' must be a mapping",
27 ));
28 }
29 let mut mapping = serde_yaml::Mapping::new();
30 mapping.insert(
31 YamlValue::String("version".into()),
32 YamlValue::Number(serde_yaml::Number::from(version_val)),
33 );
34 mapping.insert(
35 YamlValue::String("http-outbound-adapter".into()),
36 root.clone(),
37 );
38 let synthesized = YamlValue::Mapping(mapping);
39 let root: HttpOutboundAdapterSpecRootV1 = serde_yaml::from_value(synthesized)
40 .map_err(|e| Error::serialization(format!("yaml parse error: {e}")))?;
41 let blk = &root.http_outbound_adapter;
42 if blk.host.is_empty() {
43 return Err(Error::serialization(
44 "http-outbound-adapter.host must not be empty",
45 ));
46 }
47 if blk.port == 0 {
48 return Err(Error::serialization(
49 "http-outbound-adapter.port out of range (1-65535)",
50 ));
51 }
52 if let Some(bp) = &blk.base_path {
53 if bp.is_empty() || !bp.starts_with('/') {
54 return Err(Error::serialization(
55 "http-outbound-adapter.base-path must start with '/'",
56 ));
57 }
58 }
59 if let Some(p) = &blk.path {
60 if p.is_empty() || !p.starts_with('/') {
61 return Err(Error::serialization(
62 "http-outbound-adapter.path must start with '/'",
63 ));
64 }
65 }
66 if let Some(idv) = &blk.id {
67 if idv.is_empty() {
68 return Err(Error::serialization(
69 "http-outbound-adapter.id must not be empty",
70 ));
71 }
72 }
73 Ok(HttpOutboundAdapterSpec::from_block(
74 root.http_outbound_adapter,
75 ))
76 }
77 pub fn parse_str(raw: &str) -> Result<HttpOutboundAdapterSpec> {
78 let yaml: YamlValue = serde_yaml::from_str(raw)
79 .map_err(|e| Error::serialization(format!("yaml parse error: {e}")))?;
80 Self::parse_value(&yaml)
81 }
82}