1
Fork 0

some code improvements in libfmt_macros

This commit is contained in:
Simon Mazur 2015-09-10 16:48:11 +03:00
parent 69092ffdf2
commit 15d5c0878d

View file

@ -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
}
} }
} }