some code improvements in libfmt_macros
This commit is contained in:
parent
69092ffdf2
commit
15d5c0878d
1 changed files with 74 additions and 108 deletions
|
@ -151,8 +151,9 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
type Item = Piece<'a>;
|
type Item = Piece<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Piece<'a>> {
|
fn next(&mut self) -> Option<Piece<'a>> {
|
||||||
match self.cur.peek() {
|
if let Some(&(pos, c)) = self.cur.peek() {
|
||||||
Some(&(pos, '{')) => {
|
match c {
|
||||||
|
'{' => {
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
if self.consume('{') {
|
if self.consume('{') {
|
||||||
Some(String(self.string(pos + 1)))
|
Some(String(self.string(pos + 1)))
|
||||||
|
@ -162,7 +163,7 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&(pos, '}')) => {
|
'}' => {
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
if self.consume('}') {
|
if self.consume('}') {
|
||||||
Some(String(self.string(pos + 1)))
|
Some(String(self.string(pos + 1)))
|
||||||
|
@ -171,8 +172,10 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(&(pos, _)) => { Some(String(self.string(pos))) }
|
_ => Some(String(self.string(pos))),
|
||||||
None => None
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,12 +201,10 @@ impl<'a> Parser<'a> {
|
||||||
/// the current position, then the current iterator isn't moved and false is
|
/// the current position, then the current iterator isn't moved and false is
|
||||||
/// returned, otherwise the character is consumed and true is returned.
|
/// returned, otherwise the character is consumed and true is returned.
|
||||||
fn consume(&mut self, c: char) -> bool {
|
fn consume(&mut self, c: char) -> bool {
|
||||||
match self.cur.peek() {
|
if let Some(&(_, maybe)) = self.cur.peek() {
|
||||||
Some(&(_, maybe)) if c == maybe => {
|
if c == maybe { self.cur.next(); true } else { false }
|
||||||
self.cur.next();
|
} else {
|
||||||
true
|
false
|
||||||
}
|
|
||||||
Some(..) | None => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,48 +212,36 @@ impl<'a> Parser<'a> {
|
||||||
/// found, an error is emitted.
|
/// found, an error is emitted.
|
||||||
fn must_consume(&mut self, c: char) {
|
fn must_consume(&mut self, c: char) {
|
||||||
self.ws();
|
self.ws();
|
||||||
match self.cur.peek() {
|
if let Some(&(_, maybe)) = self.cur.peek() {
|
||||||
Some(&(_, maybe)) if c == maybe => {
|
if c == maybe {
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
|
} else {
|
||||||
|
self.err(&format!("expected `{:?}`, found `{:?}`", c, maybe));
|
||||||
}
|
}
|
||||||
Some(&(_, other)) => {
|
} else {
|
||||||
self.err(&format!("expected `{:?}`, found `{:?}`", c,
|
self.err(&format!("expected `{:?}` but string was terminated", c));
|
||||||
other));
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.err(&format!("expected `{:?}` but string was terminated",
|
|
||||||
c));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes all whitespace characters until the first non-whitespace
|
/// Consumes all whitespace characters until the first non-whitespace
|
||||||
/// character
|
/// character
|
||||||
fn ws(&mut self) {
|
fn ws(&mut self) {
|
||||||
loop {
|
while let Some(&(_, c)) = self.cur.peek() {
|
||||||
match self.cur.peek() {
|
if c.is_whitespace() { self.cur.next(); } else { break }
|
||||||
Some(&(_, c)) if c.is_whitespace() => { self.cur.next(); }
|
|
||||||
Some(..) | None => { return }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses all of a string which is to be considered a "raw literal" in a
|
/// Parses all of a string which is to be considered a "raw literal" in a
|
||||||
/// format string. This is everything outside of the braces.
|
/// format string. This is everything outside of the braces.
|
||||||
fn string(&mut self, start: usize) -> &'a str {
|
fn string(&mut self, start: usize) -> &'a str {
|
||||||
loop {
|
// we may not consume the character, peek the iterator
|
||||||
// we may not consume the character, so clone the iterator
|
while let Some(&(pos, c)) = self.cur.peek() {
|
||||||
match self.cur.peek() {
|
match c {
|
||||||
Some(&(pos, '}')) | Some(&(pos, '{')) => {
|
'{' | '}' => { return &self.input[start..pos]; }
|
||||||
return &self.input[start..pos];
|
_ => { self.cur.next(); }
|
||||||
}
|
|
||||||
Some(..) => { self.cur.next(); }
|
|
||||||
None => {
|
|
||||||
self.cur.next();
|
|
||||||
return &self.input[start..self.input.len()];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&self.input[start..self.input.len()]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an Argument structure, or what's contained within braces inside
|
/// Parses an Argument structure, or what's contained within braces inside
|
||||||
|
@ -267,9 +256,9 @@ impl<'a> Parser<'a> {
|
||||||
/// Parses a positional argument for a format. This could either be an
|
/// Parses a positional argument for a format. This could either be an
|
||||||
/// integer index of an argument, a named argument, or a blank string.
|
/// integer index of an argument, a named argument, or a blank string.
|
||||||
fn position(&mut self) -> Position<'a> {
|
fn position(&mut self) -> Position<'a> {
|
||||||
match self.integer() {
|
if let Some(i) = self.integer() {
|
||||||
Some(i) => { ArgumentIs(i) }
|
ArgumentIs(i)
|
||||||
None => {
|
} else {
|
||||||
match self.cur.peek() {
|
match self.cur.peek() {
|
||||||
Some(&(_, c)) if c.is_alphabetic() => {
|
Some(&(_, c)) if c.is_alphabetic() => {
|
||||||
ArgumentNamed(self.word())
|
ArgumentNamed(self.word())
|
||||||
|
@ -278,7 +267,6 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Parses a format specifier at the current position, returning all of the
|
/// Parses a format specifier at the current position, returning all of the
|
||||||
/// relevant information in the FormatSpec struct.
|
/// relevant information in the FormatSpec struct.
|
||||||
|
@ -294,18 +282,15 @@ impl<'a> Parser<'a> {
|
||||||
if !self.consume(':') { return spec }
|
if !self.consume(':') { return spec }
|
||||||
|
|
||||||
// fill character
|
// fill character
|
||||||
match self.cur.peek() {
|
if let Some(&(_, c)) = self.cur.peek() {
|
||||||
Some(&(_, c)) => {
|
|
||||||
match self.cur.clone().skip(1).next() {
|
match self.cur.clone().skip(1).next() {
|
||||||
Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
|
Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
|
||||||
spec.fill = Some(c);
|
spec.fill = Some(c);
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
}
|
}
|
||||||
Some(..) | None => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
// Alignment
|
// Alignment
|
||||||
if self.consume('<') {
|
if self.consume('<') {
|
||||||
spec.align = AlignLeft;
|
spec.align = AlignLeft;
|
||||||
|
@ -361,18 +346,15 @@ impl<'a> Parser<'a> {
|
||||||
/// for 'CountIsNextParam' because that is only used in precision, not
|
/// for 'CountIsNextParam' because that is only used in precision, not
|
||||||
/// width.
|
/// width.
|
||||||
fn count(&mut self) -> Count<'a> {
|
fn count(&mut self) -> Count<'a> {
|
||||||
match self.integer() {
|
if let Some(i) = self.integer() {
|
||||||
Some(i) => {
|
if self.consume('$') { CountIsParam(i) } else { CountIs(i) }
|
||||||
if self.consume('$') {
|
|
||||||
CountIsParam(i)
|
|
||||||
} else {
|
} else {
|
||||||
CountIs(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let tmp = self.cur.clone();
|
let tmp = self.cur.clone();
|
||||||
match self.word() {
|
let word = self.word();
|
||||||
word if !word.is_empty() => {
|
if word.is_empty() {
|
||||||
|
self.cur = tmp;
|
||||||
|
CountImplied
|
||||||
|
} else {
|
||||||
if self.consume('$') {
|
if self.consume('$') {
|
||||||
CountIsName(word)
|
CountIsName(word)
|
||||||
} else {
|
} else {
|
||||||
|
@ -380,12 +362,6 @@ impl<'a> Parser<'a> {
|
||||||
CountImplied
|
CountImplied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
self.cur = tmp;
|
|
||||||
CountImplied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,23 +370,17 @@ impl<'a> Parser<'a> {
|
||||||
/// characters.
|
/// characters.
|
||||||
fn word(&mut self) -> &'a str {
|
fn word(&mut self) -> &'a str {
|
||||||
let start = match self.cur.peek() {
|
let start = match self.cur.peek() {
|
||||||
Some(&(pos, c)) if c.is_xid_start() => {
|
Some(&(pos, c)) if c.is_xid_start() => { self.cur.next(); pos }
|
||||||
self.cur.next();
|
_ => { return &self.input[..0]; }
|
||||||
pos
|
|
||||||
}
|
|
||||||
Some(..) | None => { return &self.input[..0]; }
|
|
||||||
};
|
};
|
||||||
let end;
|
while let Some(&(pos, c)) = self.cur.peek() {
|
||||||
loop {
|
if c.is_xid_continue() {
|
||||||
match self.cur.peek() {
|
|
||||||
Some(&(_, c)) if c.is_xid_continue() => {
|
|
||||||
self.cur.next();
|
self.cur.next();
|
||||||
}
|
} else {
|
||||||
Some(&(pos, _)) => { end = pos; break }
|
return &self.input[start..pos];
|
||||||
None => { end = self.input.len(); break }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&self.input[start..end]
|
&self.input[start..self.input.len()]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Optionally parses an integer at the current position. This doesn't deal
|
/// Optionally parses an integer at the current position. This doesn't deal
|
||||||
|
@ -427,11 +397,7 @@ impl<'a> Parser<'a> {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if found {
|
if found { Some(cur) } else { None }
|
||||||
Some(cur)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue