@@ -141,10 +141,6 @@ impl cmp::Ord for Version {
141141 }
142142}
143143
144- condition ! {
145- bad_parse: ( ) -> ( ) ;
146- }
147-
148144fn take_nonempty_prefix < T : Iterator < char > > ( rdr : & mut T , pred: |char| -> bool)
149145 -> ( ~str , Option < char > ) {
150146 let mut buf = ~"";
@@ -159,53 +155,66 @@ fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
159155 }
160156 }
161157 }
162- if buf. is_empty ( ) {
163- bad_parse:: cond. raise ( ( ) )
164- }
165158 debug ! ( "extracted nonempty prefix: {}" , buf) ;
166159 ( buf, ch)
167160}
168161
169- fn take_num < T : Iterator < char > > ( rdr : & mut T ) -> ( uint , Option < char > ) {
162+ fn take_num < T : Iterator < char > > ( rdr : & mut T ) -> Option < ( uint , Option < char > ) > {
170163 let ( s, ch) = take_nonempty_prefix ( rdr, char:: is_digit) ;
171164 match from_str :: < uint > ( s) {
172- None => { bad_parse :: cond . raise ( ( ) ) ; ( 0 , ch ) } ,
173- Some ( i) => ( i, ch)
165+ None => None ,
166+ Some ( i) => Some ( ( i, ch) )
174167 }
175168}
176169
177- fn take_ident < T : Iterator < char > > ( rdr : & mut T ) -> ( Identifier , Option < char > ) {
170+ fn take_ident < T : Iterator < char > > ( rdr : & mut T ) -> Option < ( Identifier , Option < char > ) > {
178171 let ( s, ch) = take_nonempty_prefix ( rdr, char:: is_alphanumeric) ;
179172 if s. chars ( ) . all ( char:: is_digit) {
180173 match from_str :: < uint > ( s) {
181- None => { bad_parse :: cond . raise ( ( ) ) ; ( Numeric ( 0 ) , ch ) } ,
182- Some ( i) => ( Numeric ( i) , ch)
174+ None => None ,
175+ Some ( i) => Some ( ( Numeric ( i) , ch) )
183176 }
184177 } else {
185- ( AlphaNumeric ( s) , ch)
178+ Some ( ( AlphaNumeric ( s) , ch) )
186179 }
187180}
188181
189- fn expect ( ch : Option < char > , c : char ) {
182+ fn expect ( ch : Option < char > , c : char ) -> Option < ( ) > {
190183 if ch != Some ( c) {
191- bad_parse:: cond. raise ( ( ) )
184+ None
185+ } else {
186+ Some ( ( ) )
192187 }
193188}
194189
195- fn parse_iter < T : Iterator < char > > ( rdr : & mut T ) -> Version {
196- let ( major, ch) = take_num ( rdr) ;
197- expect ( ch, '.' ) ;
198- let ( minor, ch) = take_num ( rdr) ;
199- expect ( ch, '.' ) ;
200- let ( patch, ch) = take_num ( rdr) ;
190+ fn parse_iter < T : Iterator < char > > ( rdr : & mut T ) -> Option < Version > {
191+ let maybe_vers = take_num ( rdr) . and_then ( |( major, ch) | {
192+ expect ( ch, '.' ) . and_then ( |_| Some ( major) )
193+ } ) . and_then ( |major| {
194+ take_num ( rdr) . and_then ( |( minor, ch) | {
195+ expect ( ch, '.' ) . and_then ( |_| Some ( ( major, minor) ) )
196+ } )
197+ } ) . and_then ( |( major, minor) | {
198+ take_num ( rdr) . and_then ( |( patch, ch) | {
199+ Some ( ( major, minor, patch, ch) )
200+ } )
201+ } ) ;
202+
203+ let ( major, minor, patch, ch) = match maybe_vers {
204+ Some ( ( a, b, c, d) ) => ( a, b, c, d) ,
205+ None => return None
206+ } ;
201207
202208 let mut pre = ~[ ] ;
203209 let mut build = ~[ ] ;
204210
205211 let mut ch = ch;
206212 if ch == Some ( '-' ) {
207213 loop {
208- let ( id, c) = take_ident ( rdr) ;
214+ let ( id, c) = match take_ident ( rdr) {
215+ Some ( ( id, c) ) => ( id, c) ,
216+ None => return None
217+ } ;
209218 pre. push ( id) ;
210219 ch = c;
211220 if ch != Some ( '.' ) { break ; }
@@ -214,20 +223,23 @@ fn parse_iter<T: Iterator<char>>(rdr: &mut T) -> Version {
214223
215224 if ch == Some ( '+' ) {
216225 loop {
217- let ( id, c) = take_ident ( rdr) ;
226+ let ( id, c) = match take_ident ( rdr) {
227+ Some ( ( id, c) ) => ( id, c) ,
228+ None => return None
229+ } ;
218230 build. push ( id) ;
219231 ch = c;
220232 if ch != Some ( '.' ) { break ; }
221233 }
222234 }
223235
224- Version {
236+ Some ( Version {
225237 major : major,
226238 minor : minor,
227239 patch : patch,
228240 pre : pre,
229241 build : build,
230- }
242+ } )
231243}
232244
233245
@@ -237,15 +249,17 @@ pub fn parse(s: &str) -> Option<Version> {
237249 return None ;
238250 }
239251 let s = s. trim ( ) ;
240- let mut bad = false ;
241- bad_parse:: cond. trap ( |_| { debug ! ( "bad" ) ; bad = true } ) . inside ( || {
242- let v = parse_iter ( & mut s. chars ( ) ) ;
243- if bad || v. to_str ( ) != s. to_owned ( ) {
244- None
245- } else {
246- Some ( v)
252+ let v = parse_iter ( & mut s. chars ( ) ) ;
253+ match v {
254+ Some ( v) => {
255+ if v. to_str ( ) . equiv ( & s) {
256+ Some ( v)
257+ } else {
258+ None
259+ }
247260 }
248- } )
261+ None => None
262+ }
249263}
250264
251265#[ test]
0 commit comments