Skip to content

Commit

Permalink
update parser to handle new slashdash syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Dec 2, 2024
1 parent 47f86ff commit ae61060
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 147 deletions.
23 changes: 12 additions & 11 deletions src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ final;";
);

let foo = doc.get("foo").expect("expected a foo node");
assert_eq!(foo.format().map(|f| &f.trailing[..]), Some("\n"));
assert_eq!(foo.format().map(|f| &f.terminator[..]), Some("\n"));
assert_eq!(&foo[2], &"three".into());
assert_eq!(&foo["bar"], &"baz".into());
assert_eq!(
Expand Down Expand Up @@ -527,6 +527,7 @@ final;";
// if you're making KdlEntries this way, you need to inject
// your own whitespace (or format the node)
node.push(" \"blah\"=0xDEADbeef".parse::<KdlEntry>()?);
dbg!(&node);
doc.nodes_mut().push(node);

assert_eq!(
Expand Down Expand Up @@ -714,7 +715,8 @@ this {
}
// that's
nice
inline { time; to; live "our" "dreams"; "y;all"; }
inline { time; to; live "our" "dreams"; "y;all" }
"####;

let doc: KdlDocument = input.parse()?;
Expand All @@ -724,8 +726,9 @@ inline { time; to; live "our" "dreams"; "y;all"; }

// Now check some more interesting concrete spans

// The whole document should presumably be "the input" again?
check_span(input, doc.span(), &input);
// The whole document should be everything from the first node until the
// last before_terminator whitespace.
check_span(&input[1..(input.len() - 2)], doc.span(), &input);

// This one-liner node should be the whole line without leading whitespace
let is_node = doc
Expand Down Expand Up @@ -772,13 +775,11 @@ inline { time; to; live "our" "dreams"; "y;all"; }
);

// The child document is a little weird, it's the contents *inside* the braces
// with extra newlines on both ends.
// without the surrounding whitespace/comments. Just the actual contents.
check_span(
r####"{
"it" /*shh*/ "has"="💯" ##"the"##
r####""it" /*shh*/ "has"="💯" ##"the"##
Best🎊est
"syntax ever"
}"####,
"syntax ever""####,
and_node.children().unwrap().span(),
&input,
);
Expand Down Expand Up @@ -807,14 +808,14 @@ inline { time; to; live "our" "dreams"; "y;all"; }
// Make sure inline nodes work ok
let inline_node = doc.get("inline").unwrap();
check_span(
r#"inline { time; to; live "our" "dreams"; "y;all"; }"#,
r#"inline { time; to; live "our" "dreams"; "y;all" }"#,
inline_node.span(),
&input,
);

let inline_children = inline_node.children().unwrap();
check_span(
r#"{ time; to; live "our" "dreams"; "y;all"; }"#,
r#"time; to; live "our" "dreams"; "y;all" "#,
inline_children.span(),
&input,
);
Expand Down
31 changes: 22 additions & 9 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,28 +515,30 @@ impl KdlNode {
pub(crate) fn autoformat_impl(&mut self, indent: usize, no_comments: bool) {
if let Some(KdlNodeFormat {
leading,
before_terminator,
terminator,
trailing,
before_children,
..
}) = self.format_mut()
{
crate::fmt::autoformat_leading(leading, indent, no_comments);
crate::fmt::autoformat_trailing(before_terminator, no_comments);
crate::fmt::autoformat_trailing(trailing, no_comments);
*trailing = trailing.trim().into();
if trailing.starts_with(';') {
trailing.remove(0);
if !terminator.starts_with('\n') {
*terminator = "\n".into();
}
if let Some(c) = trailing.chars().next() {
if !c.is_whitespace() {
trailing.insert(0, ' ');
}
}
trailing.push('\n');

*before_children = " ".into();
} else {
self.set_format(KdlNodeFormat {
trailing: "\n".into(),
terminator: "\n".into(),
..Default::default()
})
}
Expand Down Expand Up @@ -598,8 +600,14 @@ impl KdlNode {
}
write!(f, "}}")?;
}
if let Some(KdlNodeFormat { trailing, .. }) = self.format() {
write!(f, "{}", trailing)?;
if let Some(KdlNodeFormat {
before_terminator,
terminator,
trailing,
..
}) = self.format()
{
write!(f, "{before_terminator}{terminator}{trailing}")?;
}
Ok(())
}
Expand All @@ -618,8 +626,11 @@ pub struct KdlNodeFormat {
pub after_ty: String,
/// Whitespace and comments preceding the node's children block.
pub before_children: String,
/// Whitespace and comments following the node itself, including the
/// optional semicolon.
/// Whitespace and comments right before the node's terminator.
pub before_terminator: String,
/// The terminator for the node.
pub terminator: String,
/// Whitespace and comments following the node itself, after the terminator.
pub trailing: String,
}

Expand Down Expand Up @@ -652,7 +663,9 @@ mod test {
node.format(),
Some(&KdlNodeFormat {
leading: "\n\t ".into(),
trailing: ";\n".into(),
before_terminator: "".into(),
terminator: ";".into(),
trailing: "\n".into(),
before_ty_name: "".into(),
after_ty_name: "".into(),
after_ty: "".into(),
Expand Down
Loading

0 comments on commit ae61060

Please sign in to comment.