starlane_core/config/
bind.rs1use crate::resource::{ResourceKind, ResourceAddress,ArtifactKind};
2use crate::artifact::ArtifactRef;
3use crate::cache::{Cacheable, Data};
4use crate::resource::config::{ResourceConfig, Parser};
5use crate::config::bind::yaml::BindConfigYaml;
6use std::sync::Arc;
7use crate::error::Error;
8use std::str::FromStr;
9use std::convert::TryInto;
10use starlane_resources::ResourcePath;
11
12pub struct BindConfig {
13 pub artifact: ResourcePath,
14 pub message: Message
15}
16
17impl Cacheable for BindConfig {
18 fn artifact(&self) -> ArtifactRef {
19 ArtifactRef {
20 path: self.artifact.clone(),
21 kind: ArtifactKind::BindConfig
22 }
23 }
24
25 fn references(&self) -> Vec<ArtifactRef> {
26 vec![]
27 }
28}
29
30pub struct Message {
31 pub inbound: Inbound
32}
33
34pub struct Inbound {
35 pub ports: Vec<Port>
36}
37
38pub struct Port {
39 pub name: String,
40 pub payload: Payload
41}
42
43pub struct Payload {
44 pub aspects: Vec<Aspect>
45}
46
47pub struct Aspect {
48 pub name: String,
49 pub schema: Schema
50}
51
52
53pub enum Schema {
54 HttpRequest
55}
56
57impl FromStr for Schema {
58 type Err = Error;
59
60 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 match s {
62 "http_request" => Ok(Schema::HttpRequest),
63 _ => Err(format!("not a known data schema {}",s).into())
64 }
65 }
66}
67
68pub struct BindConfigParser;
69
70impl BindConfigParser {
71 pub fn new() -> Self {
72 Self {}
73 }
74}
75
76impl Parser<BindConfig> for BindConfigParser {
77 fn parse(&self, artifact: ArtifactRef, _data: Data) -> Result<Arc<BindConfig>, Error> {
78
79 let data = String::from_utf8((*_data).clone() )?;
80 let yaml: BindConfigYaml = serde_yaml::from_str( data.as_str() )?;
81
82 let address = artifact.path.clone();
83 let bundle_address = address.parent().ok_or::<Error>("expected artifact to have bundle parent".into())?;
84
85 for p in &yaml.spec.message.inbound.ports {
87 for a in &p.payload.aspects {
88 Schema::from_str(a.schema.kind.as_str() )?;
89 }
90 }
91
92 Ok(Arc::new(BindConfig {
93 artifact: artifact.path,
94 message: Message {
95 inbound: Inbound {
96 ports: yaml.spec.message.inbound.ports.iter().map( |p| Port {
97 name: p.name.clone(),
98 payload: Payload {
99 aspects: p.payload.aspects.iter().map( |a| Aspect{
100 name: a.name.clone(),
101 schema: Schema::from_str(a.schema.kind.as_str()).expect("expected valid schema kind")
102 }).collect()
103 }
104 }).collect()
105 }
106 }
107 }))
108 }
109}
110
111mod yaml {
112 use serde::{Serialize,Deserialize};
113
114 #[derive(Clone, Serialize, Deserialize)]
115 pub struct BindConfigYaml {
116 pub kind: String,
117 pub spec: SpecYaml
118 }
119
120 #[derive(Clone, Serialize, Deserialize)]
121 pub struct SpecYaml {
122 pub name: String,
123 pub state: StateYaml,
124 pub message: MessageYaml
125 }
126
127 #[derive(Clone, Serialize, Deserialize)]
128 pub struct StateYaml{
129 pub kind: StateKindYaml
130 }
131
132 #[derive(Clone, Serialize, Deserialize)]
133 pub enum StateKindYaml{
134 Stateless
135 }
136
137
138 #[derive(Clone, Serialize, Deserialize)]
139 pub struct MessageYaml{
140 pub inbound: MessageInboundYaml
141 }
142
143 #[derive(Clone, Serialize, Deserialize)]
144 pub struct MessageInboundYaml{
145 pub ports: Vec<PortsYaml>
146 }
147
148 #[derive(Clone, Serialize, Deserialize)]
149 pub struct PortsYaml{
150 pub name: String,
151 pub payload: PayloadYaml
152 }
153
154 #[derive(Clone, Serialize, Deserialize)]
155 pub struct PayloadYaml{
156 pub aspects: Vec<AspectYaml>
157 }
158
159
160 #[derive(Clone, Serialize, Deserialize)]
161 pub struct AspectYaml{
162 pub name: String,
163 pub schema: SchemaYaml,
164 }
165
166 #[derive(Clone, Serialize, Deserialize)]
167 pub struct SchemaYaml{
168 pub kind: String,
169 pub artifact: Option<String>
170 }
171
172
173
174
175
176
177}
178
179