diff --git a/src/document.rs b/src/document.rs index 2fd3cf1..1554fc9 100644 --- a/src/document.rs +++ b/src/document.rs @@ -480,6 +480,25 @@ foo 1 bar=0xdeadbeef { Ok(()) } + #[test] + fn simple_fmt() -> miette::Result<()> { + let mut doc: KdlDocument = "a { b { c { }; }; }".parse().unwrap(); + KdlDocument::fmt(&mut doc); + print!("{}", doc); + assert_eq!( + doc.to_string(), + r#"a { + b { + c { + + } + } +} +"# + ); + Ok(()) + } + #[test] fn parse_examples() -> miette::Result<()> { include_str!("../examples/kdl-schema.kdl").parse::()?; diff --git a/src/fmt.rs b/src/fmt.rs index b6486d0..a58391b 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,3 +1,5 @@ +use std::fmt::Write as _; + pub(crate) fn fmt_leading(leading: &mut String, indent: usize, no_comments: bool) { if leading.is_empty() { return; @@ -9,11 +11,11 @@ pub(crate) fn fmt_leading(leading: &mut String, indent: usize, no_comments: bool for line in comments { let trimmed = line.trim(); if !trimmed.is_empty() { - result.push_str(&format!("{:indent$}{}\n", "", trimmed, indent = indent)); + writeln!(result, "{:indent$}{}", "", trimmed, indent = indent).unwrap(); } } } - result.push_str(&format!("{:indent$}", "", indent = indent)); + write!(result, "{:indent$}", "", indent = indent).unwrap(); *leading = result; } diff --git a/src/node.rs b/src/node.rs index 302e715..0e5fab1 100644 --- a/src/node.rs +++ b/src/node.rs @@ -369,7 +369,7 @@ impl KdlNode { } /// Represents a [`KdlNode`]'s entry key. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum NodeKey { /// Key for a node property entry. Key(KdlIdentifier), @@ -513,7 +513,10 @@ impl KdlNode { writeln!(f)?; } children.stringify(f, indent + 4)?; - write!(f, "{:indent$}}}", "", indent = indent)?; + if children.trailing.is_none() { + write!(f, "{:indent$}", "", indent = indent)?; + } + write!(f, "}}")?; } if let Some(trailing) = &self.trailing { write!(f, "{}", trailing)?; diff --git a/tests/formatting.rs b/tests/formatting.rs new file mode 100644 index 0000000..64da147 --- /dev/null +++ b/tests/formatting.rs @@ -0,0 +1,27 @@ +use kdl::{KdlDocument, KdlNode}; + +#[test] +fn build_and_format() { + let mut c = KdlNode::new("c"); + c.ensure_children(); + let mut b = KdlNode::new("b"); + b.ensure_children().nodes_mut().push(c); + let mut a = KdlNode::new("a"); + a.ensure_children().nodes_mut().push(b); + + let mut doc = KdlDocument::new(); + doc.nodes_mut().push(a); + doc.fmt(); + let fmt = doc.to_string(); + println!("{}", fmt); + assert_eq!( + fmt, + r#"a { + b { + c { + } + } +} +"# + ); +}