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