git.delta.rocks / jrsonnet / refs/commits / 8fa5c73b5fe4

difftreelog

source

crates/nixlike/src/to_string.rs2.2 KiBsourcehistory
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}2728pub fn escape_string(str: &str) -> String {29	format!(30		"\"{}\"",31		str.replace('\\', "\\\\")32			.replace('"', "\\\"")33			.replace('\n', "\\n")34			.replace('\t', "\\t")35			.replace('\r', "\\r")36			.replace('$', "\\$")37	)38}3940pub fn write_nix_str(str: &str, out: &mut String) {41	if str.ends_with('\n') {42		out.push_str("''");43		for ele in str.split('\n') {44			out.push('\n');45			out.push_str(46				&ele47					// '' is escaped with '48					.replace("''", "'''")49					// ${ is escaped wth ''50					.replace("${", "''${")51					// \t is not counted as whitespace for dedent52					// to avoid confusion, it is printed literally.53					//54					// ...Escaped \t literal should be prefixed with '' for... Idk, this logic is complicated.55					.replace('\t', "''\\t"),56			);57		}58		// Final newline is assumed due to str.ends_with condition59		out.push_str("''");60	} else {61		out.push_str(&escape_string(str))62	}63}6465fn write_nix_buf(value: &Value, out: &mut String) {66	match value {67		Value::Null => out.push_str("null"),68		Value::Boolean(v) => out.push_str(if *v { "true" } else { "false" }),69		Value::Number(n) => out.push_str(&format!("{}", n)),70		Value::String(s) => write_nix_str(s, out),71		Value::Array(a) => {72			if a.is_empty() {73				out.push_str("[ ]");74			} else {75				out.push('[');76				for item in a {77					write_nix_buf(item, out);78					out.push('\n');79				}80				out.push(']');81			}82		}83		Value::Object(obj) => {84			if obj.is_empty() {85				out.push_str("{ }")86			} else {87				out.push('{');88				for (k, v) in obj {89					write_nix_obj_key_buf(k, v, out);90					out.push('\n');91				}92				out.push('}');93			}94		}95	};96}9798pub fn write_nix(value: &Value) -> String {99	let mut out = String::new();100	write_nix_buf(value, &mut out);101	out102}