Skip to main content

hk_parser/
serialize.rs

1use crate::value::{HkConfig, HkValue};
2use indexmap::IndexMap;
3use std::fs::File;
4use std::io::{self, Write};
5use std::path::Path;
6
7/// Serializes a HkConfig back to a .hk string, preserving key order.
8pub fn serialize_hk(config: &HkConfig) -> String {
9    let mut output = String::new();
10    for (section, value) in config.iter() {
11        output.push_str(&format!("[{}]\n", section));
12        if let HkValue::Map(map) = value {
13            serialize_map(map, 1, &mut output);
14        }
15        output.push('\n');
16    }
17    output.trim_end().to_string()
18}
19
20fn serialize_map(map: &IndexMap<String, HkValue>, level: usize, output: &mut String) {
21    let prefix = "-".repeat(level) + " > ";
22    for (key, value) in map.iter() {
23        match value {
24            HkValue::Map(submap) => {
25                output.push_str(&format!("{}{}\n", prefix, key));
26                serialize_map(submap, level + 1, output);
27            }
28            _ => {
29                let val = serialize_value(value);
30                output.push_str(&format!("{}{} => {}\n", prefix, key, val));
31            }
32        }
33    }
34}
35
36fn serialize_value(value: &HkValue) -> String {
37    match value {
38        HkValue::String(s) => {
39            if s.is_empty() || s.contains(',') || s.contains(' ') || s.contains(']') || s.contains('"') || s.contains('\n') {
40                format!("\"{}\"", s.replace("\"", "\\\""))
41            } else {
42                s.clone()
43            }
44        }
45        HkValue::Number(n) => n.to_string(),
46        HkValue::Bool(b) => if *b { "true".to_string() } else { "false".to_string() },
47        HkValue::Array(a) => format!(
48            "[{}]",
49            a.iter()
50                .map(serialize_value)
51                .collect::<Vec<_>>()
52                .join(", ")
53        ),
54        HkValue::Map(_) => "<map>".to_string(),
55    }
56}
57
58pub fn write_hk_file<P: AsRef<Path>>(path: P, config: &HkConfig) -> io::Result<()> {
59    let mut file = File::create(path)?;
60    file.write_all(serialize_hk(config).as_bytes())
61}