fix(parse): small parser tweaks + more tests

This commit is contained in:
Kat Marchán 2022-04-22 23:29:45 -07:00
parent 892bf06e69
commit 1a8eb35168
4 changed files with 99 additions and 5 deletions

View File

@ -155,7 +155,7 @@ impl FromStr for KdlEntry {
type Err = KdlError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
parser::parse(s, parser::entry)
parser::parse(s, parser::entry_with_node_space)
}
}
@ -192,6 +192,37 @@ mod test {
);
}
#[test]
fn parsing() -> miette::Result<()> {
let entry: KdlEntry = " \\\n (\"m\\\"eh\")0xDEADbeef\t\\\n".parse()?;
assert_eq!(
entry,
KdlEntry {
leading: Some(" \\\n ".into()),
ty: Some("\"m\\\"eh\"".parse()?),
value: KdlValue::Base16(0xdeadbeef),
value_repr: Some("0xDEADbeef".into()),
name: None,
trailing: Some("\t\\\n".into()),
}
);
let entry: KdlEntry = " \\\n (\"m\\\"eh\")\"foo\"=0xDEADbeef\t\\\n".parse()?;
assert_eq!(
entry,
KdlEntry {
leading: Some(" \\\n ".into()),
ty: Some("\"m\\\"eh\"".parse()?),
value: KdlValue::Base16(0xdeadbeef),
value_repr: Some("0xDEADbeef".into()),
name: Some("\"foo\"".parse()?),
trailing: Some("\t\\\n".into()),
}
);
Ok(())
}
#[test]
fn display() {
let entry = KdlEntry::new(KdlValue::Base10(42));

View File

@ -160,6 +160,41 @@ impl FromStr for KdlIdentifier {
mod test {
use super::*;
#[test]
fn parsing() -> miette::Result<()> {
let plain = "foo";
assert_eq!(
plain.parse::<KdlIdentifier>()?,
KdlIdentifier {
value: plain.to_string(),
repr: Some(plain.to_string()),
}
);
let quoted = "\"foo\\\"bar\"";
assert_eq!(
quoted.parse::<KdlIdentifier>()?,
KdlIdentifier {
value: "foo\"bar".to_string(),
repr: Some(quoted.to_string()),
}
);
let invalid = "123";
assert!(invalid.parse::<KdlIdentifier>().is_err());
let invalid = " space ";
assert!(invalid.parse::<KdlIdentifier>().is_err());
let invalid = "\"x";
assert!(invalid.parse::<KdlIdentifier>().is_err());
let invalid = "r#\"foo\"#";
assert!(invalid.parse::<KdlIdentifier>().is_err());
Ok(())
}
#[test]
fn formatting() {
let plain = KdlIdentifier::from("foo");

View File

@ -441,7 +441,9 @@ impl KdlNode {
space_before_children = entry.trailing.is_none();
}
if let Some(children) = &self.children {
if space_before_children {
if let Some(before) = self.before_children() {
write!(f, "{}", before)?;
} else if space_before_children {
write!(f, " ")?;
}
write!(f, "{{")?;
@ -462,6 +464,18 @@ impl KdlNode {
mod test {
use super::*;
#[test]
fn parsing() -> miette::Result<()> {
let node: KdlNode = "\n\t (\"ty\")\"node\" 0xDEADbeef;\n".parse()?;
assert_eq!(node.leading(), Some("\n\t "));
assert_eq!(node.trailing(), Some(";\n"));
assert_eq!(node.ty(), Some(&"\"ty\"".parse()?));
assert_eq!(node.name(), &"\"node\"".parse()?);
assert_eq!(node.get(0), Some(&"0xDEADbeef".parse()?));
Ok(())
}
#[test]
fn indexing() {
let mut node = KdlNode::new("foo");

View File

@ -97,7 +97,17 @@ fn quoted_identifier(input: &str) -> IResult<&str, KdlIdentifier, KdlParseError<
Ok((input, ident))
}
pub(crate) fn entry(input: &str) -> IResult<&str, KdlEntry, KdlParseError<&str>> {
pub(crate) fn entry_with_node_space(input: &str) -> IResult<&str, KdlEntry, KdlParseError<&str>> {
let (input, leading) = recognize(many0(node_space))(input)?;
let leading = if leading.is_empty() { " " } else { leading };
let (input, mut entry) = entry(input)?;
let (input, trailing) = recognize(many0(node_space))(input)?;
entry.set_leading(leading);
entry.set_trailing(trailing);
Ok((input, entry))
}
fn entry(input: &str) -> IResult<&str, KdlEntry, KdlParseError<&str>> {
alt((property, argument))(input)
}
@ -109,7 +119,8 @@ fn property(input: &str) -> IResult<&str, KdlEntry, KdlParseError<&str>> {
let (input, (raw, value)) = context("property value", cut(value))(input)?;
let mut entry = KdlEntry::new_prop(name, value);
entry.ty = ty;
entry.set_leading(if leading.is_empty() { " " } else { leading });
entry.set_leading(leading);
entry.set_trailing("");
entry.set_value_repr(raw);
Ok((input, entry))
}
@ -124,7 +135,8 @@ fn argument(input: &str) -> IResult<&str, KdlEntry, KdlParseError<&str>> {
}?;
let mut entry = KdlEntry::new(value);
entry.ty = ty;
entry.set_leading(if leading.is_empty() { " " } else { leading });
entry.set_leading(leading);
entry.set_trailing("");
entry.set_value_repr(raw);
Ok((input, entry))
}
@ -530,6 +542,7 @@ mod node_tests {
let mut one = KdlEntry::new(1);
one.set_leading(" ");
one.set_trailing("");
one.set_value_repr("1");
assert_eq!(entries.next(), Some(&one));
@ -537,6 +550,7 @@ mod node_tests {
ident.set_repr("\"bar\"");
let mut bar = KdlEntry::new_prop(ident, false);
bar.set_leading(" ");
bar.set_trailing("");
bar.set_value_repr("false");
assert_eq!(entries.next(), Some(&bar));
}