about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-09-13 23:09:27 +0000
committerbors <bors@rust-lang.org>2015-09-13 23:09:27 +0000
commit6873b9fee4af732fe81d54fdcedbd31201e3edf0 (patch)
treec300338d7c2046314a4719cd2c488f2b88424b1f /src
parent483600e65fa90bf62491e24ed88499fe4fee819a (diff)
parent15d5c0878d93c553558bf23245c6be6f7ab65fab (diff)
downloadrust-6873b9fee4af732fe81d54fdcedbd31201e3edf0.tar.gz
rust-6873b9fee4af732fe81d54fdcedbd31201e3edf0.zip
Auto merge of #28357 - semmaz:libfmt-macros, r=alexcrichton
This changes libfmt_macros `CharIndices` iterator into `Peekable` so it can be used without `.clone()`.

Also changed some `loop match` and `match` to `while let` and `if let` respectively (mostly for readability).
Diffstat (limited to 'src')
-rw-r--r--src/libfmt_macros/lib.rs191
1 files changed, 79 insertions, 112 deletions
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 32a5bd906fc..9c02ccb08ac 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -37,6 +37,7 @@ pub use self::Count::*;
 
 use std::str;
 use std::string;
+use std::iter;
 
 /// A piece is a portion of the format string which represents the next part
 /// to emit. These are emitted as a stream by the `Parser` class.
@@ -141,7 +142,7 @@ pub enum Count<'a> {
 /// necessary there's probably lots of room for improvement performance-wise.
 pub struct Parser<'a> {
     input: &'a str,
-    cur: str::CharIndices<'a>,
+    cur: iter::Peekable<str::CharIndices<'a>>,
     /// Error messages accumulated during parsing
     pub errors: Vec<string::String>,
 }
@@ -150,28 +151,31 @@ impl<'a> Iterator for Parser<'a> {
     type Item = Piece<'a>;
 
     fn next(&mut self) -> Option<Piece<'a>> {
-        match self.cur.clone().next() {
-            Some((pos, '{')) => {
-                self.cur.next();
-                if self.consume('{') {
-                    Some(String(self.string(pos + 1)))
-                } else {
-                    let ret = Some(NextArgument(self.argument()));
-                    self.must_consume('}');
-                    ret
+        if let Some(&(pos, c)) = self.cur.peek() {
+            match c {
+                '{' => {
+                    self.cur.next();
+                    if self.consume('{') {
+                        Some(String(self.string(pos + 1)))
+                    } else {
+                        let ret = Some(NextArgument(self.argument()));
+                        self.must_consume('}');
+                        ret
+                    }
                 }
-            }
-            Some((pos, '}')) => {
-                self.cur.next();
-                if self.consume('}') {
-                    Some(String(self.string(pos + 1)))
-                } else {
-                    self.err("unmatched `}` found");
-                    None
+                '}' => {
+                    self.cur.next();
+                    if self.consume('}') {
+                        Some(String(self.string(pos + 1)))
+                    } else {
+                        self.err("unmatched `}` found");
+                        None
+                    }
                 }
+                _ => Some(String(self.string(pos))),
             }
-            Some((pos, _)) => { Some(String(self.string(pos))) }
-            None => None
+        } else {
+            None
         }
     }
 }
@@ -181,7 +185,7 @@ impl<'a> Parser<'a> {
     pub fn new(s: &'a str) -> Parser<'a> {
         Parser {
             input: s,
-            cur: s.char_indices(),
+            cur: s.char_indices().peekable(),
             errors: vec!(),
         }
     }
@@ -197,12 +201,10 @@ impl<'a> Parser<'a> {
     /// the current position, then the current iterator isn't moved and false is
     /// returned, otherwise the character is consumed and true is returned.
     fn consume(&mut self, c: char) -> bool {
-        match self.cur.clone().next() {
-            Some((_, maybe)) if c == maybe => {
-                self.cur.next();
-                true
-            }
-            Some(..) | None => false,
+        if let Some(&(_, maybe)) = self.cur.peek() {
+            if c == maybe { self.cur.next(); true } else { false }
+        } else {
+            false
         }
     }
 
@@ -210,48 +212,36 @@ impl<'a> Parser<'a> {
     /// found, an error is emitted.
     fn must_consume(&mut self, c: char) {
         self.ws();
-        match self.cur.clone().next() {
-            Some((_, maybe)) if c == maybe => {
+        if let Some(&(_, maybe)) = self.cur.peek() {
+            if c == maybe {
                 self.cur.next();
+            } else {
+                self.err(&format!("expected `{:?}`, found `{:?}`", c, maybe));
             }
-            Some((_, other)) => {
-                self.err(&format!("expected `{:?}`, found `{:?}`", c,
-                                  other));
-            }
-            None => {
-                self.err(&format!("expected `{:?}` but string was terminated",
-                                  c));
-            }
+        } else {
+            self.err(&format!("expected `{:?}` but string was terminated", c));
         }
     }
 
     /// Consumes all whitespace characters until the first non-whitespace
     /// character
     fn ws(&mut self) {
-        loop {
-            match self.cur.clone().next() {
-                Some((_, c)) if c.is_whitespace() => { self.cur.next(); }
-                Some(..) | None => { return }
-            }
+        while let Some(&(_, c)) = self.cur.peek() {
+            if c.is_whitespace() { self.cur.next(); } else { break }
         }
     }
 
     /// Parses all of a string which is to be considered a "raw literal" in a
     /// format string. This is everything outside of the braces.
     fn string(&mut self, start: usize) -> &'a str {
-        loop {
-            // we may not consume the character, so clone the iterator
-            match self.cur.clone().next() {
-                Some((pos, '}')) | Some((pos, '{')) => {
-                    return &self.input[start..pos];
-                }
-                Some(..) => { self.cur.next(); }
-                None => {
-                    self.cur.next();
-                    return &self.input[start..self.input.len()];
-                }
+        // we may not consume the character, peek the iterator
+        while let Some(&(pos, c)) = self.cur.peek() {
+            match c {
+                '{' | '}' => { return &self.input[start..pos]; }
+                _ => { self.cur.next(); }
             }
         }
+        &self.input[start..self.input.len()]
     }
 
     /// Parses an Argument structure, or what's contained within braces inside
@@ -266,15 +256,14 @@ impl<'a> Parser<'a> {
     /// Parses a positional argument for a format. This could either be an
     /// integer index of an argument, a named argument, or a blank string.
     fn position(&mut self) -> Position<'a> {
-        match self.integer() {
-            Some(i) => { ArgumentIs(i) }
-            None => {
-                match self.cur.clone().next() {
-                    Some((_, c)) if c.is_alphabetic() => {
-                        ArgumentNamed(self.word())
-                    }
-                    _ => ArgumentNext
+        if let Some(i) = self.integer() {
+            ArgumentIs(i)
+        } else {
+            match self.cur.peek() {
+                Some(&(_, c)) if c.is_alphabetic() => {
+                    ArgumentNamed(self.word())
                 }
+                _ => ArgumentNext
             }
         }
     }
@@ -293,17 +282,14 @@ impl<'a> Parser<'a> {
         if !self.consume(':') { return spec }
 
         // fill character
-        match self.cur.clone().next() {
-            Some((_, c)) => {
-                match self.cur.clone().skip(1).next() {
-                    Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
-                        spec.fill = Some(c);
-                        self.cur.next();
-                    }
-                    Some(..) | None => {}
+        if let Some(&(_, c)) = self.cur.peek() {
+            match self.cur.clone().skip(1).next() {
+                Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
+                    spec.fill = Some(c);
+                    self.cur.next();
                 }
+                _ => {}
             }
-            None => {}
         }
         // Alignment
         if self.consume('<') {
@@ -360,29 +346,20 @@ impl<'a> Parser<'a> {
     /// for 'CountIsNextParam' because that is only used in precision, not
     /// width.
     fn count(&mut self) -> Count<'a> {
-        match self.integer() {
-            Some(i) => {
+        if let Some(i) = self.integer() {
+            if self.consume('$') { CountIsParam(i) } else { CountIs(i) }
+        } else {
+            let tmp = self.cur.clone();
+            let word = self.word();
+            if word.is_empty() {
+                self.cur = tmp;
+                CountImplied
+            } else {
                 if self.consume('$') {
-                    CountIsParam(i)
+                    CountIsName(word)
                 } else {
-                    CountIs(i)
-                }
-            }
-            None => {
-                let tmp = self.cur.clone();
-                match self.word() {
-                    word if !word.is_empty() => {
-                        if self.consume('$') {
-                            CountIsName(word)
-                        } else {
-                            self.cur = tmp;
-                            CountImplied
-                        }
-                    }
-                    _ => {
-                        self.cur = tmp;
-                        CountImplied
-                    }
+                    self.cur = tmp;
+                    CountImplied
                 }
             }
         }
@@ -392,24 +369,18 @@ impl<'a> Parser<'a> {
     /// be an alphabetic character followed by any number of alphanumeric
     /// characters.
     fn word(&mut self) -> &'a str {
-        let start = match self.cur.clone().next() {
-            Some((pos, c)) if c.is_xid_start() => {
-                self.cur.next();
-                pos
-            }
-            Some(..) | None => { return &self.input[..0]; }
+        let start = match self.cur.peek() {
+            Some(&(pos, c)) if c.is_xid_start() => { self.cur.next(); pos }
+            _ => { return &self.input[..0]; }
         };
-        let end;
-        loop {
-            match self.cur.clone().next() {
-                Some((_, c)) if c.is_xid_continue() => {
-                    self.cur.next();
-                }
-                Some((pos, _)) => { end = pos; break }
-                None => { end = self.input.len(); break }
+        while let Some(&(pos, c)) = self.cur.peek() {
+            if c.is_xid_continue() {
+                self.cur.next();
+            } else {
+                return &self.input[start..pos];
             }
         }
-        &self.input[start..end]
+        &self.input[start..self.input.len()]
     }
 
     /// Optionally parses an integer at the current position. This doesn't deal
@@ -417,7 +388,7 @@ impl<'a> Parser<'a> {
     fn integer(&mut self) -> Option<usize> {
         let mut cur = 0;
         let mut found = false;
-        while let Some((_, c)) = self.cur.clone().next() {
+        while let Some(&(_, c)) = self.cur.peek() {
             if let Some(i) = c.to_digit(10) {
                 cur = cur * 10 + i as usize;
                 found = true;
@@ -426,11 +397,7 @@ impl<'a> Parser<'a> {
                 break
             }
         }
-        if found {
-            Some(cur)
-        } else {
-            None
-        }
+        if found { Some(cur) } else { None }
     }
 }