parsing out string literals in addition to paths

This commit is contained in:
Tom Alexander 2020-04-06 23:47:50 -04:00
parent 79100fc50f
commit 8bfa622c4c
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE

View File

@ -1,5 +1,4 @@
use nom::branch::alt;
use nom::bytes::complete::escaped;
use nom::bytes::complete::escaped_transform;
use nom::bytes::complete::is_a;
use nom::bytes::complete::is_not;
@ -8,7 +7,6 @@ use nom::bytes::complete::take_until;
use nom::character::complete::one_of;
use nom::character::complete::space1;
use nom::combinator::map;
use nom::combinator::not;
use nom::combinator::opt;
use nom::combinator::recognize;
use nom::combinator::rest;
@ -17,6 +15,7 @@ use nom::combinator::verify;
use nom::multi::many0;
use nom::multi::many1;
use nom::multi::separated_list;
use nom::multi::separated_nonempty_list;
use nom::sequence::delimited;
use nom::sequence::preceded;
use nom::sequence::separated_pair;
@ -97,6 +96,18 @@ struct ParameterizedBlock<'a> {
params: Vec<&'a str>,
}
#[derive(Clone, Debug, PartialEq)]
enum RValue<'a> {
RVPath(Path<'a>),
RVString(String),
}
#[derive(Clone, Debug, PartialEq)]
struct KVPair<'a> {
key: &'a str,
value: RValue<'a>,
}
#[derive(Clone, Debug, PartialEq)]
struct Body<'a> {
elements: Vec<TemplateElement<'a>>,
@ -113,18 +124,6 @@ enum TemplateElement<'a> {
TETag(DustTag<'a>),
}
#[derive(Clone, Debug, PartialEq)]
enum RValue<'a> {
RVPath(Path<'a>),
RVLiteral(&'a str),
}
#[derive(Clone, Debug, PartialEq)]
struct KVPair<'a> {
key: &'a str,
value: RValue<'a>,
}
/// Any element significant to dust that isn't plain text
///
/// These elements are always wrapped in curly braces
@ -176,12 +175,17 @@ fn key(i: &str) -> IResult<&str, &str> {
/// A series of keys separated by '.' to reference a variable in the context
fn path(i: &str) -> IResult<&str, Path> {
map(separated_list(tag("."), key), |body| Path { keys: body })(i)
map(separated_nonempty_list(tag("."), key), |body| Path {
keys: body,
})(i)
}
/// Either a literal or a path to a value
fn rvalue(i: &str) -> IResult<&str, RValue> {
map(path, RValue::RVPath)(i)
alt((
map(path, RValue::RVPath),
map(quoted_string, RValue::RVString),
))(i)
}
/// Parameters for a partial
@ -708,5 +712,26 @@ mod tests {
)
))
);
assert_eq!(
delimited(
tag("{>"),
tuple((
key,
opt(preceded(space1, separated_list(space1, key_value_pair))),
)),
tag("/}"),
)(r#"{>foo bar="ba\"z"/}"#),
Ok((
"",
(
"foo",
Some(vec![KVPair {
key: "bar",
value: RValue::RVString("ba\"z".to_owned())
}])
)
))
);
}
}