Skip to content
18 changes: 14 additions & 4 deletions src/libfmt_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ pub struct Parser<'a> {
style: Option<usize>,
/// How many newlines have been seen in the string so far, to adjust the error spans
seen_newlines: usize,
/// Start and end byte offset of every successfuly parsed argument
pub arg_places: Vec<(usize, usize)>,
}

impl<'a> Iterator for Parser<'a> {
Expand All @@ -168,9 +170,13 @@ impl<'a> Iterator for Parser<'a> {
if self.consume('{') {
Some(String(self.string(pos + 1)))
} else {
let ret = Some(NextArgument(self.argument()));
self.must_consume('}');
ret
let mut arg = self.argument();
if let Some(arg_pos) = self.must_consume('}').map(|end| {
(pos + raw + 1, end + raw + 2)
}) {
self.arg_places.push(arg_pos);
}
Some(NextArgument(arg))
}
}
'}' => {
Expand Down Expand Up @@ -211,6 +217,7 @@ impl<'a> Parser<'a> {
curarg: 0,
style,
seen_newlines: 0,
arg_places: vec![],
}
}

Expand Down Expand Up @@ -271,20 +278,22 @@ impl<'a> Parser<'a> {

/// Forces consumption of the specified character. If the character is not
/// found, an error is emitted.
fn must_consume(&mut self, c: char) {
fn must_consume(&mut self, c: char) -> Option<usize> {
self.ws();
let raw = self.style.unwrap_or(0);

let padding = raw + self.seen_newlines;
if let Some(&(pos, maybe)) = self.cur.peek() {
if c == maybe {
self.cur.next();
Some(pos)
} else {
let pos = pos + padding + 1;
self.err(format!("expected `{:?}`, found `{:?}`", c, maybe),
format!("expected `{}`", c),
pos,
pos);
None
}
} else {
let msg = format!("expected `{:?}` but string was terminated", c);
Expand All @@ -302,6 +311,7 @@ impl<'a> Parser<'a> {
} else {
self.err(msg, format!("expected `{:?}`", c), pos, pos);
}
None
}
}

Expand Down
Loading