1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use log::info;
use serde_yaml::Value;
use crate::args::Args;
use crate::errors::ProconError;
use crate::node::{Node, NodeType};
use crate::nodes::Nodes;
#[cfg(test)]
#[path = "./yaml_file_reader_test.rs"]
mod yaml_file_reader_test;
pub struct YamlFileReader {}
impl YamlFileReader {
pub fn parse(_args: &Args, content: &String) -> Result<Nodes, ProconError> {
info!("Use YamlFileReader");
let yaml_value: Value = serde_yaml::from_str(&content).map_err(|_| ProconError {
message: "Wrong yaml format".to_string(),
})?;
Self::convert_yaml_values_to_nodes(&yaml_value)
}
fn convert_yaml_values_to_nodes(yaml_value: &Value) -> Result<Nodes, ProconError> {
let mut nodes: Nodes = Nodes::new();
match yaml_value {
Value::Mapping(ref obj) => {
for (map_key, map_value) in obj.iter() {
let mut parent =
Self::yaml_to_node(map_key.as_str().unwrap(), &map_value, None, 0).unwrap();
nodes.merge(&mut parent);
}
}
Value::Sequence(yaml_value) => {
let mut parent = Node::new_from_name("");
let mut children: Vec<String> = vec![];
for value in yaml_value.iter() {
let string_value = Self::yaml_value_to_string(value);
children.push(string_value);
}
parent.value = NodeType::ARRAY(children);
nodes.merge(&mut parent);
}
_ => eprintln!("not valid yaml"),
}
Ok(nodes)
}
fn yaml_to_node(
key: &str,
value: &Value,
parent: Option<&mut Node>,
level: usize,
) -> Option<Node> {
let mut new_node: Node;
if level == 0 {
new_node = Node::new_from_name(key);
} else {
new_node = Node::new_child(level, parent.unwrap(), key);
}
let new_node_option = match value {
Value::Bool(yaml_value) => {
new_node.value = NodeType::parse(&yaml_value.to_string());
Some(new_node)
}
Value::Number(yaml_value) => {
new_node.value = NodeType::parse(&yaml_value.to_string());
Some(new_node)
}
Value::String(yaml_value) => {
new_node.value = NodeType::parse(yaml_value);
Some(new_node)
}
Value::Sequence(yaml_value) => {
let mut children: Vec<String> = vec![];
for value in yaml_value.iter() {
let string_value = Self::yaml_value_to_string(value);
children.push(string_value);
}
new_node.value = NodeType::ARRAY(children);
Some(new_node)
}
Value::Mapping(yaml_value) => {
let mut children: Vec<Node> = vec![];
for (map_key, map_value) in yaml_value.iter() {
let child_node = Self::yaml_to_node(
map_key.as_str().unwrap(),
map_value,
Some(&mut new_node),
level + 1,
);
if child_node.is_some() {
children.push(child_node.unwrap());
}
}
new_node.children = children;
Some(new_node)
}
Value::Tagged(_) => None,
Value::Null => None,
};
new_node_option
}
fn yaml_value_to_string(value: &Value) -> String {
if value.is_number() {
return value.as_f64().unwrap().to_string();
}
if value.is_bool() {
return value.as_bool().unwrap().to_string();
}
value.as_str().unwrap().to_string()
}
}