Skip to content

Commit 2291721

Browse files
authored
Merge pull request #2231 from LeSeulArtichaut/cleanup-toolchain-parsing
Cleanup toolchain parsing
2 parents 8e03e74 + d8e8022 commit 2291721

File tree

1 file changed

+62
-50
lines changed

1 file changed

+62
-50
lines changed

src/dist/dist.rs

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@ static TOOLCHAIN_CHANNELS: &[&str] = &[
3030
r"\d{1}\.\d{1,3}\.\d{1,2}",
3131
];
3232

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>,
4138
}
4239

4340
// A toolchain descriptor from rustup's perspective. These contain
@@ -137,6 +134,43 @@ static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64-unknown-linux-gnuabi
137134
#[cfg(all(not(windows), target_endian = "little"))]
138135
static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64el-unknown-linux-gnuabi64";
139136

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+
140174
impl TargetTriple {
141175
pub fn new(name: &str) -> Self {
142176
Self(name.to_string())
@@ -297,29 +331,17 @@ impl PartialTargetTriple {
297331
impl FromStr for PartialToolchainDesc {
298332
type Err = Error;
299333
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,
315343
})
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())
323345
}
324346
}
325347

@@ -376,27 +398,17 @@ impl PartialToolchainDesc {
376398
impl FromStr for ToolchainDesc {
377399
type Err = Error;
378400
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()?;
392402

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+
})
400412
}
401413
}
402414

0 commit comments

Comments
 (0)