kv3/
to_string.rs

1use crate::Value;
2
3pub fn to_string(value: &Value) -> String {
4    fn format_indent(indent_level: usize) -> String {
5        "\t".repeat(indent_level)
6    }
7
8    fn to_string_with_indent(value: &Value, indent_level: usize) -> String {
9        let prev_indent = format_indent(indent_level - 1);
10        let curr_indent = format_indent(indent_level);
11
12        match value {
13            Value::File(header, root) => {
14                format!("{}\n{}", header, to_string_with_indent(root, indent_level))
15            }
16            Value::Object(map) => {
17                if map.is_empty() {
18                    return format!("{{\n{}}}", prev_indent);
19                }
20
21                let pairs = map
22                    .iter()
23                    .map(|(key, value)| {
24                        let separator = if value.is_object() || value.is_array() {
25                            format!("\n{}", format_indent(indent_level))
26                        } else {
27                            " ".to_owned()
28                        };
29                        format!(
30                            "{}{} ={}{}",
31                            curr_indent,
32                            key,
33                            separator,
34                            to_string_with_indent(value, indent_level + 1)
35                        )
36                    })
37                    .collect::<Vec<_>>()
38                    .join("\n");
39
40                format!("{{\n{}\n{}}}", pairs, prev_indent)
41            }
42
43            Value::Array(values) => {
44                if values.is_empty() {
45                    return format!("[\n{}]", prev_indent);
46                }
47
48                let elements = values
49                    .iter()
50                    .map(|value| {
51                        format!(
52                            "{}{}",
53                            curr_indent,
54                            to_string_with_indent(value, indent_level + 1)
55                        )
56                    })
57                    .collect::<Vec<_>>()
58                    .join(",\n");
59
60                format!("[\n{},\n{}]", elements, prev_indent)
61            }
62
63            Value::Flag(key, value) => {
64                let separator = if value.is_object() || value.is_array() {
65                    format!("\n{}", prev_indent)
66                } else {
67                    "".to_owned()
68                };
69
70                format!(
71                    "{}:{}{}",
72                    key,
73                    separator,
74                    to_string_with_indent(value, indent_level)
75                )
76            }
77
78            Value::String(value) => format!("\"{}\"", value),
79            Value::MultilineString(value) => format!("\"\"\"\n{}\n\"\"\"\n", value),
80            Value::Number(value) => value.to_string(),
81            Value::Bool(value) => value.to_string(),
82            Value::Null => "null".to_string(),
83        }
84    }
85
86    to_string_with_indent(value, 1).trim_end().to_string() + "\n"
87}