auto merge of #11296 : brson/rust/anti-cond, r=alexcrichton

In preparation for removing conditions.
This commit is contained in:
bors 2014-01-06 21:51:38 -08:00
commit 07950e740c
1 changed files with 48 additions and 34 deletions

View File

@ -141,10 +141,6 @@ impl cmp::Ord for Version {
} }
} }
condition! {
bad_parse: () -> ();
}
fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool) fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
-> (~str, Option<char>) { -> (~str, Option<char>) {
let mut buf = ~""; let mut buf = ~"";
@ -159,45 +155,55 @@ fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
} }
} }
} }
if buf.is_empty() {
bad_parse::cond.raise(())
}
debug!("extracted nonempty prefix: {}", buf); debug!("extracted nonempty prefix: {}", buf);
(buf, ch) (buf, ch)
} }
fn take_num<T: Iterator<char>>(rdr: &mut T) -> (uint, Option<char>) { fn take_num<T: Iterator<char>>(rdr: &mut T) -> Option<(uint, Option<char>)> {
let (s, ch) = take_nonempty_prefix(rdr, char::is_digit); let (s, ch) = take_nonempty_prefix(rdr, char::is_digit);
match from_str::<uint>(s) { match from_str::<uint>(s) {
None => { bad_parse::cond.raise(()); (0, ch) }, None => None,
Some(i) => (i, ch) Some(i) => Some((i, ch))
} }
} }
fn take_ident<T: Iterator<char>>(rdr: &mut T) -> (Identifier, Option<char>) { fn take_ident<T: Iterator<char>>(rdr: &mut T) -> Option<(Identifier, Option<char>)> {
let (s,ch) = take_nonempty_prefix(rdr, char::is_alphanumeric); let (s,ch) = take_nonempty_prefix(rdr, char::is_alphanumeric);
if s.chars().all(char::is_digit) { if s.chars().all(char::is_digit) {
match from_str::<uint>(s) { match from_str::<uint>(s) {
None => { bad_parse::cond.raise(()); (Numeric(0), ch) }, None => None,
Some(i) => (Numeric(i), ch) Some(i) => Some((Numeric(i), ch))
} }
} else { } else {
(AlphaNumeric(s), ch) Some((AlphaNumeric(s), ch))
} }
} }
fn expect(ch: Option<char>, c: char) { fn expect(ch: Option<char>, c: char) -> Option<()> {
if ch != Some(c) { if ch != Some(c) {
bad_parse::cond.raise(()) None
} else {
Some(())
} }
} }
fn parse_iter<T: Iterator<char>>(rdr: &mut T) -> Version { fn parse_iter<T: Iterator<char>>(rdr: &mut T) -> Option<Version> {
let (major, ch) = take_num(rdr); let maybe_vers = take_num(rdr).and_then(|(major, ch)| {
expect(ch, '.'); expect(ch, '.').and_then(|_| Some(major))
let (minor, ch) = take_num(rdr); }).and_then(|major| {
expect(ch, '.'); take_num(rdr).and_then(|(minor, ch)| {
let (patch, ch) = take_num(rdr); expect(ch, '.').and_then(|_| Some((major, minor)))
})
}).and_then(|(major, minor)| {
take_num(rdr).and_then(|(patch, ch)| {
Some((major, minor, patch, ch))
})
});
let (major, minor, patch, ch) = match maybe_vers {
Some((a, b, c, d)) => (a, b, c, d),
None => return None
};
let mut pre = ~[]; let mut pre = ~[];
let mut build = ~[]; let mut build = ~[];
@ -205,7 +211,10 @@ fn parse_iter<T: Iterator<char>>(rdr: &mut T) -> Version {
let mut ch = ch; let mut ch = ch;
if ch == Some('-') { if ch == Some('-') {
loop { loop {
let (id, c) = take_ident(rdr); let (id, c) = match take_ident(rdr) {
Some((id, c)) => (id, c),
None => return None
};
pre.push(id); pre.push(id);
ch = c; ch = c;
if ch != Some('.') { break; } if ch != Some('.') { break; }
@ -214,20 +223,23 @@ fn parse_iter<T: Iterator<char>>(rdr: &mut T) -> Version {
if ch == Some('+') { if ch == Some('+') {
loop { loop {
let (id, c) = take_ident(rdr); let (id, c) = match take_ident(rdr) {
Some((id, c)) => (id, c),
None => return None
};
build.push(id); build.push(id);
ch = c; ch = c;
if ch != Some('.') { break; } if ch != Some('.') { break; }
} }
} }
Version { Some(Version {
major: major, major: major,
minor: minor, minor: minor,
patch: patch, patch: patch,
pre: pre, pre: pre,
build: build, build: build,
} })
} }
@ -237,15 +249,17 @@ pub fn parse(s: &str) -> Option<Version> {
return None; return None;
} }
let s = s.trim(); let s = s.trim();
let mut bad = false; let v = parse_iter(&mut s.chars());
bad_parse::cond.trap(|_| { debug!("bad"); bad = true }).inside(|| { match v {
let v = parse_iter(&mut s.chars()); Some(v) => {
if bad || v.to_str() != s.to_owned() { if v.to_str().equiv(&s) {
None Some(v)
} else { } else {
Some(v) None
}
} }
}) None => None
}
} }
#[test] #[test]