git.delta.rocks / jrsonnet / refs/commits / c007b07c706f

difftreelog

source

crates/nixlike/src/to_string.rs3.1 KiBsourcehistory
1use crate::Value;2use dprint_core::formatting::{3	condition_resolvers, conditions, format, ConditionResolverContext, Info, PrintItems,4	PrintOptions, Signal,5};67fn write_nix_obj_key_buf(k: &str, v: &Value, out: &mut PrintItems) {8	if k.contains(".") {9		out.push_str("\"");10		out.push_str(k);11		out.push_str("\"");12	} else {13		out.push_str(k);14	}15	match v {16		Value::Object(o) if o.len() == 1 => {17			let (k, v) = o.iter().next().unwrap();1819			out.push_str(".");20			write_nix_obj_key_buf(k, v, out);21		}22		v => {23			out.push_str(" = ");24			write_nix_buf(v, out);25			out.push_str(";");26		}27	}28}2930fn write_nix_buf(value: &Value, out: &mut PrintItems) {31	match value {32		Value::Null => out.push_str("null"),33		Value::Boolean(v) => out.push_str(if *v { "true" } else { "false" }),34		Value::Number(n) => out.push_str(&format!("{}", n)),35		Value::String(s) => out.push_str(&format!(36			"\"{}\"",37			s.replace('\\', "\\\\")38				.replace('"', "\\\"")39				.replace('\n', "\\n")40				.replace('\t', "\\t")41				.replace('\r', "\\r")42				.replace("$", "\\$")43		)),44		Value::Array(a) => {45			if a.is_empty() {46				out.push_str("[ ]");47			} else {48				let start_info = Info::new("start");49				let end_info = Info::new("end");50				let is_multiple_lines = move |ctx: &mut ConditionResolverContext| {51					condition_resolvers::is_multiple_lines(ctx, &start_info, &end_info)52				};53				out.push_str("[");54				out.push_info(start_info);55				out.push_signal(Signal::StartIndent);56				out.push_condition(conditions::if_true_or(57					"array start",58					is_multiple_lines,59					Signal::NewLine.into(),60					Signal::SpaceOrNewLine.into(),61				));62				for item in a {63					write_nix_buf(item, out);64					out.push_condition(conditions::if_true_or(65						"element separator",66						is_multiple_lines,67						Signal::NewLine.into(),68						Signal::SpaceOrNewLine.into(),69					));70				}71				out.push_signal(Signal::FinishIndent);72				out.push_info(end_info);73				out.push_str("]");74			}75		}76		Value::Object(obj) => {77			if obj.is_empty() {78				out.push_str("{ }")79			} else {80				let start_info = Info::new("start");81				let end_info = Info::new("end");82				let is_multiple_lines = move |ctx: &mut ConditionResolverContext| {83					condition_resolvers::is_multiple_lines(ctx, &start_info, &end_info)84				};85				out.push_str("{");86				out.push_info(start_info);87				out.push_signal(Signal::StartIndent);88				out.push_condition(conditions::if_true_or(89					"object start",90					is_multiple_lines,91					Signal::NewLine.into(),92					Signal::SpaceOrNewLine.into(),93				));94				for (k, v) in obj {95					write_nix_obj_key_buf(k, v, out);96					out.push_condition(conditions::if_true_or(97						"element separator",98						is_multiple_lines,99						Signal::NewLine.into(),100						Signal::SpaceOrNewLine.into(),101					));102				}103				out.push_signal(Signal::FinishIndent);104				out.push_info(end_info);105				out.push_str("}");106			}107		}108	};109}110111pub fn write_nix(value: &Value) -> String {112	format(113		|| {114			let mut items = PrintItems::new();115			write_nix_buf(value, &mut items);116			items117		},118		PrintOptions {119			max_width: 120,120			use_tabs: false,121			indent_width: 2,122			new_line_text: "\n",123		},124	)125}