template: parameters not in last position are mishandled

This commit is contained in:
Joshua M. Clulow 2021-07-02 00:11:48 +00:00
parent 9c90253237
commit 0ddb6bbb7c
1 changed files with 23 additions and 3 deletions

View File

@ -1,4 +1,4 @@
use anyhow::{Result, bail};
use anyhow::{anyhow, bail, Context, Result};
#[derive(Eq, PartialEq, Clone, Debug)]
enum Component {
@ -34,10 +34,16 @@ impl Template {
}
pub fn parse(t: &str) -> Result<Template> {
parse_inner(t)
.with_context(|| anyhow!("parse failure for template {:?}", t))
}
fn parse_inner(t: &str) -> Result<Template> {
enum State {
Start,
ConstantOrParameter,
Parameter,
ParameterSlash,
Constant,
}
@ -79,19 +85,26 @@ pub fn parse(t: &str) -> Result<Template> {
if c == '}' {
components.push(Component::Parameter(a));
a = String::new();
s = State::ConstantOrParameter;
s = State::ParameterSlash;
} else if c == '/' || c == '{' {
bail!("expected parameter");
} else {
a.push(c);
}
}
State::ParameterSlash => {
if c == '/' {
s = State::ConstantOrParameter;
} else {
bail!("expected a slash after parameter");
}
}
}
}
match s {
State::Start => bail!("empty path"),
State::ConstantOrParameter => (),
State::ConstantOrParameter | State::ParameterSlash => (),
State::Constant => components.push(Component::Constant(a)),
State::Parameter => bail!("unterminated parameter"),
}
@ -118,6 +131,13 @@ mod test {
Component::Parameter("number".into()),
],
}),
("/one/{two}/three", Template {
components: vec![
Component::Constant("one".into()),
Component::Parameter("two".into()),
Component::Constant("three".into()),
],
}),
];
for (path, want) in trials.iter() {