@@ -30,14 +30,11 @@ static TOOLCHAIN_CHANNELS: &[&str] = &[
30
30
r"\d{1}\.\d{1,3}\.\d{1,2}" ,
31
31
] ;
32
32
33
- lazy_static ! {
34
- static ref TOOLCHAIN_CHANNEL_PATTERN : String = format!(
35
- r"^({})(?:-(\d{{4}}-\d{{2}}-\d{{2}}))?(?:-(.*))?$" ,
36
- TOOLCHAIN_CHANNELS . join( "|" )
37
- ) ;
38
- // Note this regex gives you a guaranteed match of the channel (1)
39
- // and an optional match of the date (2) and target (3)
40
- static ref TOOLCHAIN_CHANNEL_RE : Regex = Regex :: new( & TOOLCHAIN_CHANNEL_PATTERN ) . unwrap( ) ;
33
+ #[ derive( Debug ) ]
34
+ struct ParsedToolchainDesc {
35
+ channel : String ,
36
+ date : Option < String > ,
37
+ target : Option < String > ,
41
38
}
42
39
43
40
// A toolchain descriptor from rustup's perspective. These contain
@@ -137,6 +134,43 @@ static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64-unknown-linux-gnuabi
137
134
#[ cfg( all( not( windows) , target_endian = "little" ) ) ]
138
135
static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64 : & str = "mips64el-unknown-linux-gnuabi64" ;
139
136
137
+ impl FromStr for ParsedToolchainDesc {
138
+ type Err = Error ;
139
+ fn from_str ( desc : & str ) -> Result < Self > {
140
+ lazy_static ! {
141
+ static ref TOOLCHAIN_CHANNEL_PATTERN : String = format!(
142
+ r"^({})(?:-(\d{{4}}-\d{{2}}-\d{{2}}))?(?:-(.*))?$" ,
143
+ TOOLCHAIN_CHANNELS . join( "|" )
144
+ ) ;
145
+ // Note this regex gives you a guaranteed match of the channel (1)
146
+ // and an optional match of the date (2) and target (3)
147
+ static ref TOOLCHAIN_CHANNEL_RE : Regex = Regex :: new( & TOOLCHAIN_CHANNEL_PATTERN ) . unwrap( ) ;
148
+ }
149
+
150
+ let d = TOOLCHAIN_CHANNEL_RE . captures ( desc) . map ( |c| {
151
+ fn fn_map ( s : & str ) -> Option < String > {
152
+ if s == "" {
153
+ None
154
+ } else {
155
+ Some ( s. to_owned ( ) )
156
+ }
157
+ }
158
+
159
+ Self {
160
+ channel : c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_owned ( ) ,
161
+ date : c. get ( 2 ) . map ( |s| s. as_str ( ) ) . and_then ( fn_map) ,
162
+ target : c. get ( 3 ) . map ( |s| s. as_str ( ) ) . and_then ( fn_map) ,
163
+ }
164
+ } ) ;
165
+
166
+ if let Some ( d) = d {
167
+ Ok ( d)
168
+ } else {
169
+ Err ( ErrorKind :: InvalidToolchainName ( desc. to_string ( ) ) . into ( ) )
170
+ }
171
+ }
172
+ }
173
+
140
174
impl TargetTriple {
141
175
pub fn new ( name : & str ) -> Self {
142
176
Self ( name. to_string ( ) )
@@ -297,29 +331,17 @@ impl PartialTargetTriple {
297
331
impl FromStr for PartialToolchainDesc {
298
332
type Err = Error ;
299
333
fn from_str ( name : & str ) -> Result < Self > {
300
- let d = TOOLCHAIN_CHANNEL_RE . captures ( name) . map ( |c| {
301
- fn fn_map ( s : & str ) -> Option < String > {
302
- if s == "" {
303
- None
304
- } else {
305
- Some ( s. to_owned ( ) )
306
- }
307
- }
308
-
309
- let trip = c. get ( 3 ) . map ( |c| c. as_str ( ) ) . unwrap_or ( "" ) ;
310
- let trip = PartialTargetTriple :: new ( & trip) ;
311
- trip. map ( |t| Self {
312
- channel : c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_owned ( ) ,
313
- date : c. get ( 2 ) . map ( |s| s. as_str ( ) ) . and_then ( fn_map) ,
314
- target : t,
334
+ let parsed: ParsedToolchainDesc = name. parse ( ) ?;
335
+ let target =
336
+ PartialTargetTriple :: new ( parsed. target . as_ref ( ) . map ( |c| c. as_str ( ) ) . unwrap_or ( "" ) ) ;
337
+
338
+ target
339
+ . map ( |target| Self {
340
+ channel : parsed. channel ,
341
+ date : parsed. date ,
342
+ target,
315
343
} )
316
- } ) ;
317
-
318
- if let Some ( Some ( d) ) = d {
319
- Ok ( d)
320
- } else {
321
- Err ( ErrorKind :: InvalidToolchainName ( name. to_string ( ) ) . into ( ) )
322
- }
344
+ . ok_or_else ( || ErrorKind :: InvalidToolchainName ( name. to_string ( ) ) . into ( ) )
323
345
}
324
346
}
325
347
@@ -376,27 +398,17 @@ impl PartialToolchainDesc {
376
398
impl FromStr for ToolchainDesc {
377
399
type Err = Error ;
378
400
fn from_str ( name : & str ) -> Result < Self > {
379
- TOOLCHAIN_CHANNEL_RE
380
- . captures ( name)
381
- // Filter out cases where the target wasn't specified, so we report
382
- // an invalid toolchain name for that.
383
- . filter ( |c| c. get ( 3 ) . is_some ( ) )
384
- . map ( |c| {
385
- fn fn_map ( s : & str ) -> Option < String > {
386
- if s == "" {
387
- None
388
- } else {
389
- Some ( s. to_owned ( ) )
390
- }
391
- }
401
+ let parsed: ParsedToolchainDesc = name. parse ( ) ?;
392
402
393
- Self {
394
- channel : c. get ( 1 ) . unwrap ( ) . as_str ( ) . to_owned ( ) ,
395
- date : c. get ( 2 ) . map ( |s| s. as_str ( ) ) . and_then ( fn_map) ,
396
- target : TargetTriple ( c. get ( 3 ) . unwrap ( ) . as_str ( ) . to_owned ( ) ) ,
397
- }
398
- } )
399
- . ok_or_else ( || ErrorKind :: InvalidToolchainName ( name. to_string ( ) ) . into ( ) )
403
+ if parsed. target . is_none ( ) {
404
+ return Err ( ErrorKind :: InvalidToolchainName ( name. to_string ( ) ) . into ( ) ) ;
405
+ }
406
+
407
+ Ok ( Self {
408
+ channel : parsed. channel ,
409
+ date : parsed. date ,
410
+ target : TargetTriple ( parsed. target . unwrap ( ) ) ,
411
+ } )
400
412
}
401
413
}
402
414
0 commit comments