y2hcl/
lib.rs

1extern crate serde_yaml;
2
3pub fn run(yaml_data: serde_yaml::Value, format: String) {
4    let mut keys_result: Vec<String> = Vec::new();
5    let mut values_result: Vec<String> = Vec::new();
6
7    for (key, value) in yaml_data.as_mapping().unwrap() {
8        handle_all_root_value_types(key, value, &mut keys_result, &mut values_result)
9    }
10
11    display_output(format, keys_result, values_result);
12}
13
14fn handle_root_bool_value_type(
15    key: &str,
16    value: &serde_yaml::Value,
17    keys_result: &mut Vec<String>,
18    values_result: &mut Vec<String>,
19) {
20    if value.is_bool() {
21        values_result.push(value.as_bool().unwrap().to_string());
22        keys_result.push(key.to_string());
23    }
24}
25
26fn handle_root_string_value_type(
27    key: &str,
28    value: &serde_yaml::Value,
29    keys_result: &mut Vec<String>,
30    values_result: &mut Vec<String>,
31) {
32    if value.is_string() {
33        values_result.push(value.as_str().unwrap().to_string());
34        keys_result.push(key.to_string());
35    }
36}
37
38fn handle_root_number_value_type(
39    key: &str,
40    value: &serde_yaml::Value,
41    keys_result: &mut Vec<String>,
42    values_result: &mut Vec<String>,
43) {
44    if value.is_number() {
45        if value.is_i64() {
46            values_result.push(value.as_i64().unwrap().to_string());
47            keys_result.push(key.to_string());
48        } else if value.is_f64() {
49            values_result.push(value.as_f64().unwrap().to_string());
50            keys_result.push(key.to_string());
51        }
52    }
53}
54
55fn handle_root_sequence_value_type_recursively(
56    key: &str,
57    value: &serde_yaml::Value,
58    keys_result: &mut Vec<String>,
59    values_result: &mut Vec<String>,
60) -> (Vec<String>, Vec<String>) {
61    if value.is_sequence() {
62        for item in value.as_sequence().unwrap() {
63            if item.is_sequence() {
64                handle_root_sequence_value_type_recursively(key, item, keys_result, values_result);
65            } else if item.is_mapping() {
66                handle_root_mapping_value_type_recursively(key, item, keys_result, values_result);
67            }
68        }
69    }
70
71    (keys_result.to_vec(), values_result.to_vec())
72}
73
74fn handle_root_mapping_value_type_recursively(
75    key: &str,
76    map_value: &serde_yaml::Value,
77    keys_result: &mut Vec<String>,
78    values_result: &mut Vec<String>,
79) -> (Vec<String>, Vec<String>) {
80    if map_value.is_mapping() {
81        for (sub_key, sub_value) in map_value.as_mapping().unwrap() {
82            let new_sub_key = format!("{}.{}", key, &sub_key.as_str().unwrap());
83
84            handle_root_bool_value_type(&new_sub_key, sub_value, keys_result, values_result);
85            handle_root_number_value_type(&new_sub_key, sub_value, keys_result, values_result);
86            handle_root_string_value_type(&new_sub_key, sub_value, keys_result, values_result);
87            handle_root_mapping_value_type_recursively(
88                &new_sub_key,
89                sub_value,
90                keys_result,
91                values_result,
92            );
93            handle_root_sequence_value_type_recursively(
94                &new_sub_key,
95                sub_value,
96                keys_result,
97                values_result,
98            );
99        }
100    }
101
102    (keys_result.to_vec(), values_result.to_vec())
103}
104
105fn handle_all_root_value_types(
106    key: &serde_yaml::Value,
107    value: &serde_yaml::Value,
108    keys_result: &mut Vec<String>,
109    values_result: &mut Vec<String>,
110) {
111    let new_key = key.as_str().unwrap();
112
113    handle_root_bool_value_type(new_key, value, keys_result, values_result);
114    handle_root_number_value_type(new_key, value, keys_result, values_result);
115    handle_root_string_value_type(new_key, value, keys_result, values_result);
116    handle_root_sequence_value_type_recursively(new_key, value, keys_result, values_result);
117    handle_root_mapping_value_type_recursively(new_key, value, keys_result, values_result);
118}
119
120fn display_output(format: String, keys: Vec<String>, values: Vec<String>) {
121    match &format as &str {
122        "hcl_map" => print_hcl_map(keys, values), // Terraform varible of type map
123        "set_value" => print_helm_release_set_value(keys, values), // Terraform helm_release provider set_value
124        "sensitive_value" => print_helm_release_sensitive_set_value(keys, values), // Terraform helm_release provider sensitive_value
125        "helm_cli" => print_helm_cli_set_value(keys, values), // Helm Chart Cli set value
126        _ => (),
127    }
128}
129
130fn print_hcl_map(keys: Vec<String>, values: Vec<String>) {
131    println!("hcl_map = {{");
132    for (key, value) in keys.iter().zip(values.iter()) {
133        println!("  \"{}\" = \"{}\"", key, value)
134    }
135    println!("}}");
136}
137
138fn print_helm_release_set_value(keys: Vec<String>, values: Vec<String>) {
139    for (key, value) in keys.iter().zip(values.iter()) {
140        println!(
141            r#"
142    set_value = {{
143      name = "{}"
144      value = "{}"
145    }}
146    "#,
147            key, value
148        );
149    }
150}
151
152fn print_helm_release_sensitive_set_value(keys: Vec<String>, values: Vec<String>) {
153    for (key, value) in keys.iter().zip(values.iter()) {
154        println!(
155            r#"
156    set_sensitive = {{
157      name = "{}"
158      value = "{}"
159    }}
160    "#,
161            key, value
162        );
163    }
164}
165
166fn print_helm_cli_set_value(keys: Vec<String>, values: Vec<String>) {
167    for (key, value) in keys.iter().zip(values.iter()) {
168        println!("--set {}=\"{}\" \\", key, value);
169    }
170}
171
172#[cfg(test)]
173mod tests {
174    use super::*;
175
176    #[test]
177    fn parse_bool_value_from_yaml() {
178        let mut keys_result: Vec<String> = Vec::new();
179        let mut values_result: Vec<String> = Vec::new();
180
181        let yaml_input: serde_yaml::Value =
182            serde_yaml::from_str("enable_ssl: true").expect("Failed to parse YAML");
183
184        for (key, value) in yaml_input.as_mapping().unwrap() {
185            let new_key = key.as_str().unwrap();
186            handle_root_bool_value_type(new_key, value, &mut keys_result, &mut values_result);
187        }
188
189        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
190
191        let expected_keys_result = ["enable_ssl"];
192        let expected_values_result = ["true"];
193        assert_eq!(keys_result, expected_keys_result);
194        assert_eq!(values_result, expected_values_result);
195    }
196
197    #[test]
198    fn parse_string_value_from_yaml() {
199        let mut keys_result: Vec<String> = Vec::new();
200        let mut values_result: Vec<String> = Vec::new();
201
202        let yaml_input: serde_yaml::Value =
203            serde_yaml::from_str("protocol_type: http").expect("Failed to parse YAML");
204
205        for (key, value) in yaml_input.as_mapping().unwrap() {
206            let new_key = key.as_str().unwrap();
207            handle_root_string_value_type(new_key, value, &mut keys_result, &mut values_result);
208        }
209
210        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
211
212        let expected_keys_result = ["protocol_type"];
213        let expected_values_result = ["http"];
214        assert_eq!(keys_result, expected_keys_result);
215        assert_eq!(values_result, expected_values_result);
216    }
217
218    #[test]
219    fn parse_i64_value_from_yaml() {
220        let mut keys_result: Vec<String> = Vec::new();
221        let mut values_result: Vec<String> = Vec::new();
222
223        let yaml_input: serde_yaml::Value =
224            serde_yaml::from_str("port: 8080").expect("Failed to parse YAML");
225
226        for (key, value) in yaml_input.as_mapping().unwrap() {
227            let new_key = key.as_str().unwrap();
228            handle_root_number_value_type(new_key, value, &mut keys_result, &mut values_result);
229        }
230
231        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
232        println!("{:?}", values_result[0].parse::<i64>().unwrap());
233
234        let expected_keys_result = ["port"];
235        let expected_values_result = ["8080"];
236        assert_eq!(keys_result, expected_keys_result);
237        assert_eq!(values_result, expected_values_result);
238    }
239
240    #[test]
241    fn parse_f64_value_from_yaml() {
242        let mut keys_result: Vec<String> = Vec::new();
243        let mut values_result: Vec<String> = Vec::new();
244
245        let yaml_input: serde_yaml::Value =
246            serde_yaml::from_str("some_price: 200.44").expect("Failed to parse YAML");
247
248        for (key, value) in yaml_input.as_mapping().unwrap() {
249            let new_key = key.as_str().unwrap();
250            handle_root_number_value_type(new_key, value, &mut keys_result, &mut values_result);
251        }
252
253        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
254        println!("{:?}", values_result[0].parse::<f64>().unwrap());
255
256        let expected_keys_result = ["some_price"];
257        let expected_values_result = ["200.44"];
258        assert_eq!(keys_result, expected_keys_result);
259        assert_eq!(values_result, expected_values_result);
260    }
261
262    #[test]
263    fn parse_sequance_value_from_yaml() {
264        let mut keys_result: Vec<String> = Vec::new();
265        let mut values_result: Vec<String> = Vec::new();
266
267        let yaml_input: serde_yaml::Value = serde_yaml::from_str(
268            r#"
269  imagePullSecrets:
270    - name: docker-pull-secret
271"#,
272        )
273        .expect("Failed to parse YAML");
274
275        for (key, value) in yaml_input.as_mapping().unwrap() {
276            let new_key = key.as_str().unwrap();
277            handle_root_sequence_value_type_recursively(
278                new_key,
279                value,
280                &mut keys_result,
281                &mut values_result,
282            );
283        }
284
285        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
286
287        let expected_keys_result = ["imagePullSecrets.name"];
288        let expected_values_result = ["docker-pull-secret"];
289        assert_eq!(keys_result, expected_keys_result);
290        assert_eq!(values_result, expected_values_result);
291    }
292
293    #[test]
294    fn parse_mapping_value_from_yaml() {
295        let mut keys_result: Vec<String> = Vec::new();
296        let mut values_result: Vec<String> = Vec::new();
297
298        let yaml_input: serde_yaml::Value = serde_yaml::from_str(
299            r#"
300cleanup_job:
301  imagePullSecrets:
302    - name: docker-pull-secret
303"#,
304        )
305        .expect("Failed to parse YAML");
306
307        for (key, value) in yaml_input.as_mapping().unwrap() {
308            let new_key = key.as_str().unwrap();
309            handle_root_mapping_value_type_recursively(
310                new_key,
311                value,
312                &mut keys_result,
313                &mut values_result,
314            );
315        }
316
317        println!("Keys: {:?}, Values: {:?}", keys_result, values_result);
318
319        let expected_keys_result = ["cleanup_job.imagePullSecrets.name"];
320        let expected_values_result = ["docker-pull-secret"];
321        assert_eq!(keys_result, expected_keys_result);
322        assert_eq!(values_result, expected_values_result);
323    }
324}