data_modelling_sdk/export/
dataflow.rs1use crate::models::{DataModel, Relationship, Table};
7use serde_yaml;
8
9pub struct DataFlowExporter;
11
12impl Default for DataFlowExporter {
13 fn default() -> Self {
14 Self::new()
15 }
16}
17
18impl DataFlowExporter {
19 pub fn new() -> Self {
29 Self
30 }
31
32 pub fn export_model(model: &DataModel) -> String {
56 let mut yaml = serde_yaml::Mapping::new();
57
58 let nodes: Vec<serde_yaml::Value> =
60 model.tables.iter().map(Self::export_node_to_yaml).collect();
61 if !nodes.is_empty() {
62 yaml.insert(
63 serde_yaml::Value::String("nodes".to_string()),
64 serde_yaml::Value::Sequence(nodes),
65 );
66 }
67
68 let relationships: Vec<serde_yaml::Value> = model
70 .relationships
71 .iter()
72 .map(Self::export_relationship_to_yaml)
73 .collect();
74 if !relationships.is_empty() {
75 yaml.insert(
76 serde_yaml::Value::String("relationships".to_string()),
77 serde_yaml::Value::Sequence(relationships),
78 );
79 }
80
81 serde_yaml::to_string(&yaml).unwrap_or_default()
82 }
83
84 pub fn export_node(table: &Table) -> String {
94 let yaml_value = Self::export_node_to_yaml(table);
95 serde_yaml::to_string(&yaml_value).unwrap_or_default()
96 }
97
98 pub fn export_relationship(relationship: &Relationship) -> String {
108 let yaml_value = Self::export_relationship_to_yaml(relationship);
109 serde_yaml::to_string(&yaml_value).unwrap_or_default()
110 }
111
112 fn export_node_to_yaml(table: &Table) -> serde_yaml::Value {
113 let mut node = serde_yaml::Mapping::new();
114
115 node.insert(
116 serde_yaml::Value::String("id".to_string()),
117 serde_yaml::Value::String(table.id.to_string()),
118 );
119 node.insert(
120 serde_yaml::Value::String("name".to_string()),
121 serde_yaml::Value::String(table.name.clone()),
122 );
123 node.insert(
124 serde_yaml::Value::String("type".to_string()),
125 serde_yaml::Value::String("table".to_string()),
126 );
127
128 let columns: Vec<serde_yaml::Value> = table
130 .columns
131 .iter()
132 .map(|col| {
133 let mut col_map = serde_yaml::Mapping::new();
134 col_map.insert(
135 serde_yaml::Value::String("name".to_string()),
136 serde_yaml::Value::String(col.name.clone()),
137 );
138 col_map.insert(
139 serde_yaml::Value::String("type".to_string()),
140 serde_yaml::Value::String(col.data_type.clone()),
141 );
142 serde_yaml::Value::Mapping(col_map)
143 })
144 .collect();
145 if !columns.is_empty() {
146 node.insert(
147 serde_yaml::Value::String("columns".to_string()),
148 serde_yaml::Value::Sequence(columns),
149 );
150 }
151
152 let metadata = Self::export_metadata_to_yaml(
154 table.owner.as_deref(),
155 table.sla.as_ref(),
156 table.contact_details.as_ref(),
157 table.infrastructure_type,
158 table.notes.as_deref(),
159 );
160 if let Some(meta) = metadata {
161 node.insert(serde_yaml::Value::String("metadata".to_string()), meta);
162 }
163
164 serde_yaml::Value::Mapping(node)
165 }
166
167 fn export_relationship_to_yaml(relationship: &Relationship) -> serde_yaml::Value {
168 let mut rel = serde_yaml::Mapping::new();
169
170 rel.insert(
171 serde_yaml::Value::String("id".to_string()),
172 serde_yaml::Value::String(relationship.id.to_string()),
173 );
174 rel.insert(
175 serde_yaml::Value::String("source_node_id".to_string()),
176 serde_yaml::Value::String(relationship.source_table_id.to_string()),
177 );
178 rel.insert(
179 serde_yaml::Value::String("target_node_id".to_string()),
180 serde_yaml::Value::String(relationship.target_table_id.to_string()),
181 );
182
183 let metadata = Self::export_metadata_to_yaml(
185 relationship.owner.as_deref(),
186 relationship.sla.as_ref(),
187 relationship.contact_details.as_ref(),
188 relationship.infrastructure_type,
189 relationship.notes.as_deref(),
190 );
191 if let Some(meta) = metadata {
192 rel.insert(serde_yaml::Value::String("metadata".to_string()), meta);
193 }
194
195 serde_yaml::Value::Mapping(rel)
196 }
197
198 fn export_metadata_to_yaml(
199 owner: Option<&str>,
200 sla: Option<&Vec<crate::models::SlaProperty>>,
201 contact_details: Option<&crate::models::ContactDetails>,
202 infrastructure_type: Option<crate::models::enums::InfrastructureType>,
203 notes: Option<&str>,
204 ) -> Option<serde_yaml::Value> {
205 let mut has_metadata = false;
206 let mut metadata = serde_yaml::Mapping::new();
207
208 if let Some(owner_str) = owner {
209 metadata.insert(
210 serde_yaml::Value::String("owner".to_string()),
211 serde_yaml::Value::String(owner_str.to_string()),
212 );
213 has_metadata = true;
214 }
215
216 if let Some(sla_vec) = sla {
217 let sla_yaml: Vec<serde_yaml::Value> = sla_vec
218 .iter()
219 .map(|sla_prop| {
220 let mut sla_map = serde_yaml::Mapping::new();
221 sla_map.insert(
222 serde_yaml::Value::String("property".to_string()),
223 serde_yaml::Value::String(sla_prop.property.clone()),
224 );
225 sla_map.insert(
226 serde_yaml::Value::String("value".to_string()),
227 Self::json_value_to_yaml(&sla_prop.value),
228 );
229 sla_map.insert(
230 serde_yaml::Value::String("unit".to_string()),
231 serde_yaml::Value::String(sla_prop.unit.clone()),
232 );
233 if let Some(ref element) = sla_prop.element {
234 sla_map.insert(
235 serde_yaml::Value::String("element".to_string()),
236 serde_yaml::Value::String(element.clone()),
237 );
238 }
239 if let Some(ref driver) = sla_prop.driver {
240 sla_map.insert(
241 serde_yaml::Value::String("driver".to_string()),
242 serde_yaml::Value::String(driver.clone()),
243 );
244 }
245 if let Some(ref description) = sla_prop.description {
246 sla_map.insert(
247 serde_yaml::Value::String("description".to_string()),
248 serde_yaml::Value::String(description.clone()),
249 );
250 }
251 if let Some(ref scheduler) = sla_prop.scheduler {
252 sla_map.insert(
253 serde_yaml::Value::String("scheduler".to_string()),
254 serde_yaml::Value::String(scheduler.clone()),
255 );
256 }
257 if let Some(ref schedule) = sla_prop.schedule {
258 sla_map.insert(
259 serde_yaml::Value::String("schedule".to_string()),
260 serde_yaml::Value::String(schedule.clone()),
261 );
262 }
263 serde_yaml::Value::Mapping(sla_map)
264 })
265 .collect();
266 metadata.insert(
267 serde_yaml::Value::String("sla".to_string()),
268 serde_yaml::Value::Sequence(sla_yaml),
269 );
270 has_metadata = true;
271 }
272
273 if let Some(contact) = contact_details {
274 let mut contact_map = serde_yaml::Mapping::new();
275 if let Some(ref email) = contact.email {
276 contact_map.insert(
277 serde_yaml::Value::String("email".to_string()),
278 serde_yaml::Value::String(email.clone()),
279 );
280 }
281 if let Some(ref phone) = contact.phone {
282 contact_map.insert(
283 serde_yaml::Value::String("phone".to_string()),
284 serde_yaml::Value::String(phone.clone()),
285 );
286 }
287 if let Some(ref name) = contact.name {
288 contact_map.insert(
289 serde_yaml::Value::String("name".to_string()),
290 serde_yaml::Value::String(name.clone()),
291 );
292 }
293 if let Some(ref role) = contact.role {
294 contact_map.insert(
295 serde_yaml::Value::String("role".to_string()),
296 serde_yaml::Value::String(role.clone()),
297 );
298 }
299 if let Some(ref other) = contact.other {
300 contact_map.insert(
301 serde_yaml::Value::String("other".to_string()),
302 serde_yaml::Value::String(other.clone()),
303 );
304 }
305 if !contact_map.is_empty() {
306 metadata.insert(
307 serde_yaml::Value::String("contact_details".to_string()),
308 serde_yaml::Value::Mapping(contact_map),
309 );
310 has_metadata = true;
311 }
312 }
313
314 if let Some(infra_type) = infrastructure_type {
315 let infra_str = serde_json::to_string(&infra_type)
317 .unwrap_or_default()
318 .trim_matches('"')
319 .to_string();
320 metadata.insert(
321 serde_yaml::Value::String("infrastructure_type".to_string()),
322 serde_yaml::Value::String(infra_str),
323 );
324 has_metadata = true;
325 }
326
327 if let Some(notes_str) = notes {
328 metadata.insert(
329 serde_yaml::Value::String("notes".to_string()),
330 serde_yaml::Value::String(notes_str.to_string()),
331 );
332 has_metadata = true;
333 }
334
335 if has_metadata {
336 Some(serde_yaml::Value::Mapping(metadata))
337 } else {
338 None
339 }
340 }
341
342 fn json_value_to_yaml(json: &serde_json::Value) -> serde_yaml::Value {
343 match json {
344 serde_json::Value::Null => serde_yaml::Value::Null,
345 serde_json::Value::Bool(b) => serde_yaml::Value::Bool(*b),
346 serde_json::Value::Number(n) => {
347 if let Some(i) = n.as_i64() {
348 serde_yaml::Value::Number(serde_yaml::Number::from(i))
349 } else if let Some(f) = n.as_f64() {
350 serde_yaml::Value::Number(serde_yaml::Number::from(f))
351 } else {
352 serde_yaml::Value::String(n.to_string())
353 }
354 }
355 serde_json::Value::String(s) => serde_yaml::Value::String(s.clone()),
356 serde_json::Value::Array(arr) => {
357 let yaml_arr: Vec<serde_yaml::Value> =
358 arr.iter().map(Self::json_value_to_yaml).collect();
359 serde_yaml::Value::Sequence(yaml_arr)
360 }
361 serde_json::Value::Object(obj) => {
362 let mut yaml_map = serde_yaml::Mapping::new();
363 for (k, v) in obj {
364 yaml_map.insert(
365 serde_yaml::Value::String(k.clone()),
366 Self::json_value_to_yaml(v),
367 );
368 }
369 serde_yaml::Value::Mapping(yaml_map)
370 }
371 }
372 }
373}