1use crate::Value;23fn write_nix_obj_key_buf(k: &str, v: &Value, out: &mut String) {4 if k.contains('.') {5 out.push_str("\"");6 out.push_str(k);7 out.push_str("\"");8 } else {9 out.push_str(k);10 }11 match v {12 Value::Object(o) if o.len() == 1 => {13 let (k, v) = o.iter().next().unwrap();1415 out.push_str(".");16 write_nix_obj_key_buf(k, v, out);17 }18 v => {19 out.push_str(" = ");20 write_nix_buf(v, out);21 out.push_str(";");22 }23 }24}2526fn write_nix_str(str: &str, out: &mut String) {27 out.push_str(&format!(28 "\"{}\"",29 str.replace('\\', "\\\\")30 .replace('"', "\\\"")31 .replace('\n', "\\n")32 .replace('\t', "\\t")33 .replace('\r', "\\r")34 .replace('$', "\\$")35 ))36}3738fn write_nix_buf(value: &Value, out: &mut String) {39 match value {40 Value::Null => out.push_str("null"),41 Value::Boolean(v) => out.push_str(if *v { "true" } else { "false" }),42 Value::Number(n) => out.push_str(&format!("{}", n)),43 Value::String(s) => write_nix_str(s, out),44 Value::Array(a) => {45 if a.is_empty() {46 out.push_str("[ ]");47 } else {48 out.push('[');49 for item in a {50 write_nix_buf(item, out);51 out.push('\n');52 }53 out.push(']');54 }55 }56 Value::Object(obj) => {57 if obj.is_empty() {58 out.push_str("{ }")59 } else {60 out.push('{');61 for (k, v) in obj {62 write_nix_obj_key_buf(k, v, out);63 out.push('\n');64 }65 out.push('}');66 }67 }68 };69}7071pub fn write_nix(value: &Value) -> String {72 let mut out = String::new();73 write_nix_buf(value, &mut out);74 let (_, out) = alejandra::format::in_memory("".to_owned(), out);75 out76}