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
use crate::*;
pub trait Dumper {
fn ind(level: usize) -> String {
" ".repeat(level)
}
fn dump(&self, level: usize, wrap: bool) -> String;
}
impl Dumper for Node {
fn dump(&self, level: usize, wrap: bool) -> String {
let mut doc = String::new();
if !self.anchor.is_empty() {
doc += &format!("&{} ", self.anchor);
}
if !self.ty.is_empty() {
doc += &format!("!!{} ", self.ty);
}
let ind = Self::ind(level);
doc += &match &self.yaml {
Yaml::Null => "null".into(),
Yaml::Bool(b) => b.to_string(),
Yaml::Int(n) | Yaml::Float(n) => n.clone(),
Yaml::Str(s) => {
if s.contains("\n") {
let s = s.trim().replace("\n", &(String::from("\n") + &ind));
String::from("|\n") + &ind + &s
} else {
s.clone()
}
}
Yaml::Array(a) => {
let mut doc = String::from(if level == 0 { "" } else { "\n" });
for (i, node) in a.iter().enumerate() {
if i != 0 || level != 0 {
doc += &ind;
}
doc += &format!("- {}\n", node.dump(level + 1, false));
}
doc.pop();
doc
}
Yaml::Map(m) => {
let mut doc = String::from(if wrap { "\n" } else { "" });
for (i, (k, v)) in m.iter().enumerate() {
if i != 0 || wrap {
doc += &ind;
}
let s = k.dump(level + 1, false);
if let Yaml::Map(_) | Yaml::Array(_) = k.yaml {
doc += "?\n";
doc += &(Self::ind(level + 1) + "\n" + &s + "\n" + &ind);
} else {
doc += &s;
}
doc += ": ";
doc += &(v.dump(level + 1, true) + "\n");
}
doc.pop();
doc
}
Yaml::Anchor(anchor) => format!("*{}", anchor),
};
doc
}
}
pub fn dump<I>(nodes: I) -> String
where
I: IntoIterator,
I::Item: Dumper,
{
nodes
.into_iter()
.enumerate()
.map(|(i, node)| {
String::from(if i == 0 { "" } else { "---\n" })
+ &node
.dump(0, false)
.split('\n')
.map(|s| s.trim_end())
.collect::<Vec<_>>()
.join("\n")
+ "\n"
})
.collect()
}