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

difftreelog

feat dprint support

Yaroslav Bolyukin2021-09-18parent: #f965cc1.patch.diff
in: trunk

2 files changed

modifiedcrates/nixlike/src/lib.rsdiffbeforeafterboth
before · crates/nixlike/src/lib.rs
1use std::collections::BTreeMap;23use peg::str::LineCol;4use se_impl::MySerialize;5use serde::{Deserialize, Serialize};67mod de_impl;8mod se_impl;9mod to_string;1011#[derive(thiserror::Error, Debug)]12pub enum Error {13	#[error("bad number")]14	BadNumber,15	#[error("expected {0}")]16	Expected(&'static str),17	#[error("parse error")]18	ParseError(#[from] peg::error::ParseError<LineCol>),19	#[error("{0}")]20	Custom(String),21	#[error("io: {0}")]22	Io(#[from] std::io::Error),23	#[error("fmt: {0}")]24	Fmt(#[from] std::fmt::Error),25}2627#[derive(Debug)]28pub enum Value {29	Number(i64),30	String(String),31	Boolean(bool),32	Object(BTreeMap<String, Value>),33	Array(Vec<Value>),34	Null,35}3637peg::parser! {38pub grammar nixlike() for str {39	rule number() -> i6440		= quiet! { v:$(['0'..='9' | '+' | '-']+) {? v.parse().map_err(|_| "<number>")} } / expected!("<number>")41	rule string_char() -> &'input str42		= "\\\"" { "\"" }43		/ "\\\\" { "\\" }44		/ c:$([_]) { c }45	rule string() -> String46		= quiet! { "\"" v:(!"\"" c:string_char() {c})* "\"" { v.into_iter().collect() } } / expected!("<string>")47	rule boolean() -> bool48		= quiet! { "true" {true}49		/ "false" {false} } / expected!("<boolean>")50	rule indent() -> String51		= quiet! { s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() } } / expected!("<identifier>")52	rule object() -> BTreeMap<String, Value>53		= "{" _54			e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*55		"}" {?56			let mut out = BTreeMap::new();57			for (k, v) in e {58				let mut map = &mut out;59				for v in k.iter().take(k.len() - 1) {60					map = match map.entry(v.clone()).or_insert_with(|| Value::Object(Default::default())) {61						Value::Object(v) => v,62						_ => return Err("expected object"),63					}64				}6566				let key = k.into_iter().last().unwrap();67				if map.contains_key(&key) {68					return Err("can't override object");69				}70				map.insert(key, v);71			}72			Ok(out)73		}7475	rule array() -> Vec<Value>76		= "[" _ v:value()**_ _ "]" {v}7778	rule value() -> Value79		= o:object() { Value::Object(o) }80		/ a:array() { Value::Array(a) }81		/ s:string() { Value::String(s) }82		/ "null" { Value::Null }83		/ b:boolean() { Value::Boolean(b) }84		/ n:number() { Value::Number(n) }8586	pub rule root() -> Value87		= _ v:value() _ { v }8889	rule _()90		= ( quiet!{ [' ' | '\t' | '\n']+ }91		/ "#" (!['\n'] [_])* "\n" )*92}93}9495pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {96	let value = nixlike::root(s)?;97	D::deserialize(value)98}99100pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {101	D::deserialize(value)102}103104pub fn serialize_value_pretty(value: Value) -> Result<String, Error> {105	to_string::write_nix(&value)106}107108pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {109	let value: Value = value.serialize(MySerialize)?;110	serialize_value_pretty(value)111}112113#[test]114fn test() {115	let v: serde_json::Value = parse_str(116		r#"117			{118				b.c = 2;119				b.d = "hello";120				c = {121					k = 123;122					p = 231;123					ll = [1 2 3 [] [[4 5 6]] ];124				};125			}126		"#,127	)128	.unwrap();129	let s: String = serialize(v).unwrap();130	println!("{}", s);131}
after · crates/nixlike/src/lib.rs
1use std::collections::BTreeMap;23use peg::str::LineCol;4use se_impl::MySerialize;5use serde::{Deserialize, Serialize};67mod de_impl;8mod se_impl;9mod to_string;1011#[derive(thiserror::Error, Debug)]12pub enum Error {13	#[error("bad number")]14	BadNumber,15	#[error("expected {0}")]16	Expected(&'static str),17	#[error("parse error")]18	ParseError(#[from] peg::error::ParseError<LineCol>),19	#[error("{0}")]20	Custom(String),21	#[error("io: {0}")]22	Io(#[from] std::io::Error),23	#[error("fmt: {0}")]24	Fmt(#[from] std::fmt::Error),25}2627#[derive(Debug)]28pub enum Value {29	Number(i64),30	String(String),31	Boolean(bool),32	Object(BTreeMap<String, Value>),33	Array(Vec<Value>),34	Null,35}3637peg::parser! {38pub grammar nixlike() for str {39	rule number() -> i6440		= quiet! { v:$(['0'..='9' | '+' | '-']+) {? v.parse().map_err(|_| "<number>")} } / expected!("<number>")41	rule string_char() -> &'input str42		= "\\\"" { "\"" }43		/ "\\\\" { "\\" }44		/ c:$([_]) { c }45	rule string() -> String46		= quiet! { "\"" v:(!"\"" c:string_char() {c})* "\"" { v.into_iter().collect() } } / expected!("<string>")47	rule boolean() -> bool48		= quiet! { "true" {true}49		/ "false" {false} } / expected!("<boolean>")50	rule indent() -> String51		= quiet! { s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() } } / expected!("<identifier>")52	rule object() -> BTreeMap<String, Value>53		= "{" _54			e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*55		"}" {?56			let mut out = BTreeMap::new();57			for (k, v) in e {58				let mut map = &mut out;59				for v in k.iter().take(k.len() - 1) {60					map = match map.entry(v.clone()).or_insert_with(|| Value::Object(Default::default())) {61						Value::Object(v) => v,62						_ => return Err("expected object"),63					}64				}6566				let key = k.into_iter().last().unwrap();67				if map.contains_key(&key) {68					return Err("can't override object");69				}70				map.insert(key, v);71			}72			Ok(out)73		}7475	rule array() -> Vec<Value>76		= "[" _ v:value()**_ _ "]" {v}7778	rule value() -> Value79		= o:object() { Value::Object(o) }80		/ a:array() { Value::Array(a) }81		/ s:string() { Value::String(s) }82		/ "null" { Value::Null }83		/ b:boolean() { Value::Boolean(b) }84		/ n:number() { Value::Number(n) }8586	pub rule root() -> Value87		= _ v:value() _ { v }8889	rule _()90		= ( quiet!{ [' ' | '\t' | '\n']+ }91		/ "#" (!['\n'] [_])* "\n" )*92}93}9495pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {96	let value = nixlike::root(s)?;97	D::deserialize(value)98}99100pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {101	D::deserialize(value)102}103104pub fn serialize_value_pretty(value: Value) -> String {105	to_string::write_nix(&value)106}107108pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {109	let value: Value = value.serialize(MySerialize)?;110	Ok(serialize_value_pretty(value))111}112113#[test]114fn test() {115	let v: serde_json::Value = parse_str(116		r#"117			{118				b.c = 2;119				b.d = "hello";120				c = {121					k = 123;122					p = 231;123					ll = [1 2 3 [] [[4 5 6]] ];124				};125			}126		"#,127	)128	.unwrap();129	let s: String = serialize(v).unwrap();130	println!("{}", s);131}
modifiedcrates/nixlike/src/to_string.rsdiffbeforeafterboth
--- 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<String, Error> {
-	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",
+		},
+	)
 }