--- a/crates/nixlike/src/lib.rs +++ b/crates/nixlike/src/lib.rs @@ -101,13 +101,13 @@ D::deserialize(value) } -pub fn serialize_value_pretty(value: Value) -> Result { +pub fn serialize_value_pretty(value: Value) -> String { to_string::write_nix(&value) } pub fn serialize(value: S) -> Result { let value: Value = value.serialize(MySerialize)?; - serialize_value_pretty(value) + Ok(serialize_value_pretty(value)) } #[test] --- a/crates/nixlike/src/to_string.rs +++ b/crates/nixlike/src/to_string.rs @@ -1,74 +1,111 @@ -use crate::{Error, Value}; +use crate::Value; +use dprint_core::formatting::{ + condition_resolvers, conditions, format, ConditionResolverContext, Info, PrintItems, + PrintOptions, Signal, +}; -fn write_nix_obj_key_buf( - k: &str, - v: &Value, - out: &mut String, - indent: &mut String, -) -> Result<(), Error> { - use std::fmt::Write; - write!(out, "{}", k)?; +fn write_nix_obj_key_buf(k: &str, v: &Value, out: &mut PrintItems) { + out.push_str(k); match v { Value::Object(o) if o.len() == 1 => { let (k, v) = o.iter().next().unwrap(); - write!(out, ".")?; - write_nix_obj_key_buf(k, v, out, indent)?; + + out.push_str("."); + write_nix_obj_key_buf(k, v, out); } v => { - write!(out, " = ")?; - write_nix_buf(v, out, indent)?; - writeln!(out, ";")?; + out.push_str(" = "); + write_nix_buf(v, out); + out.push_str(";"); } } - Ok(()) } -fn write_nix_buf(value: &Value, out: &mut String, indent: &mut String) -> Result<(), Error> { - use std::fmt::Write; +fn write_nix_buf(value: &Value, out: &mut PrintItems) { match value { - Value::Null => write!(out, "null")?, - Value::Boolean(v) => write!(out, "{:?}", v)?, - Value::Number(n) => write!(out, "{}", n)?, - Value::String(s) => write!(out, "{:?}", s)?, + Value::Null => out.push_str("null"), + Value::Boolean(v) => out.push_str(if *v { "true" } else { "false" }), + Value::Number(n) => out.push_str(&format!("{}", n)), + Value::String(s) => out.push_str(&format!("{:?}", s)), Value::Array(a) => { if a.is_empty() { - write!(out, "[ ]")?; + out.push_str("[ ]"); } else { - writeln!(out, "[")?; - let old_len = indent.len(); - indent.push_str(" "); + let start_info = Info::new("start"); + let end_info = Info::new("end"); + let is_multiple_lines = move |ctx: &mut ConditionResolverContext| { + condition_resolvers::is_multiple_lines(ctx, &start_info, &end_info) + }; + out.push_str("["); + out.push_info(start_info); + out.push_signal(Signal::StartIndent); + out.push_condition(conditions::if_true_or( + "array start", + is_multiple_lines.clone(), + Signal::NewLine.into(), + Signal::SpaceOrNewLine.into(), + )); for item in a { - write!(out, "{}", indent)?; - write_nix_buf(item, out, indent)?; - writeln!(out)?; + write_nix_buf(item, out); + out.push_condition(conditions::if_true_or( + "element separator", + is_multiple_lines.clone(), + Signal::NewLine.into(), + Signal::SpaceOrNewLine.into(), + )); } - indent.truncate(old_len); - write!(out, "{}]", indent)?; + out.push_signal(Signal::FinishIndent); + out.push_info(end_info); + out.push_str("]"); } } Value::Object(obj) => { if obj.is_empty() { - write!(out, "{{ }}")?; + out.push_str("{ }") } else { - writeln!(out, "{{")?; - let old_len = indent.len(); - indent.push_str(" "); + let start_info = Info::new("start"); + let end_info = Info::new("end"); + let is_multiple_lines = move |ctx: &mut ConditionResolverContext| { + condition_resolvers::is_multiple_lines(ctx, &start_info, &end_info) + }; + out.push_str("{"); + out.push_info(start_info); + out.push_signal(Signal::StartIndent); + out.push_condition(conditions::if_true_or( + "object start", + is_multiple_lines.clone(), + Signal::NewLine.into(), + Signal::SpaceOrNewLine.into(), + )); for (k, v) in obj { - write!(out, "{}", indent)?; - write_nix_obj_key_buf(k, v, out, indent)?; + write_nix_obj_key_buf(k, v, out); + out.push_condition(conditions::if_true_or( + "element separator", + is_multiple_lines.clone(), + Signal::NewLine.into(), + Signal::SpaceOrNewLine.into(), + )); } - indent.truncate(old_len); - write!(out, "{}}}", indent)?; + out.push_signal(Signal::FinishIndent); + out.push_info(end_info); + out.push_str("}"); } } }; - Ok(()) } - -pub fn write_nix(value: &Value) -> Result { - let mut out = String::new(); - let mut indent = String::new(); - write_nix_buf(value, &mut out, &mut indent)?; - Ok(out) +pub fn write_nix(value: &Value) -> String { + format( + || { + let mut items = PrintItems::new(); + write_nix_buf(value, &mut items); + items + }, + PrintOptions { + max_width: 120, + use_tabs: false, + indent_width: 2, + new_line_text: "\n", + }, + ) }