You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.1 KiB
115 lines
3.1 KiB
use self::Channel::*;
|
|
use std::fmt::{self, Debug};
|
|
|
|
#[cfg_attr(test, derive(PartialEq))]
|
|
pub struct Version {
|
|
pub minor: u16,
|
|
pub patch: u16,
|
|
pub channel: Channel,
|
|
}
|
|
|
|
#[cfg_attr(test, derive(PartialEq))]
|
|
pub enum Channel {
|
|
Stable,
|
|
Beta,
|
|
Nightly(Date),
|
|
Dev,
|
|
}
|
|
|
|
#[cfg_attr(test, derive(PartialEq))]
|
|
pub struct Date {
|
|
pub year: u16,
|
|
pub month: u8,
|
|
pub day: u8,
|
|
}
|
|
|
|
pub fn parse(string: &str) -> Option<Version> {
|
|
let last_line = string.lines().last().unwrap_or(&string);
|
|
let mut words = last_line.trim().split(' ');
|
|
|
|
if words.next()? != "rustc" {
|
|
return None;
|
|
}
|
|
|
|
let mut version_channel = words.next()?.split('-');
|
|
let version = version_channel.next()?;
|
|
let channel = version_channel.next();
|
|
|
|
let mut digits = version.split('.');
|
|
let major = digits.next()?;
|
|
if major != "1" {
|
|
return None;
|
|
}
|
|
let minor = digits.next()?.parse().ok()?;
|
|
let patch = digits.next().unwrap_or("0").parse().ok()?;
|
|
|
|
let channel = match channel {
|
|
None => Stable,
|
|
Some(channel) if channel == "dev" => Dev,
|
|
Some(channel) if channel.starts_with("beta") => Beta,
|
|
Some(channel) if channel == "nightly" => match words.next() {
|
|
Some(hash) => {
|
|
if !hash.starts_with('(') {
|
|
return None;
|
|
}
|
|
let date = words.next()?;
|
|
if !date.ends_with(')') {
|
|
return None;
|
|
}
|
|
let mut date = date[..date.len() - 1].split('-');
|
|
let year = date.next()?.parse().ok()?;
|
|
let month = date.next()?.parse().ok()?;
|
|
let day = date.next()?.parse().ok()?;
|
|
match date.next() {
|
|
None => Nightly(Date { year, month, day }),
|
|
Some(_) => return None,
|
|
}
|
|
}
|
|
None => Dev,
|
|
},
|
|
Some(_) => return None,
|
|
};
|
|
|
|
Some(Version {
|
|
minor,
|
|
patch,
|
|
channel,
|
|
})
|
|
}
|
|
|
|
impl Debug for Version {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
formatter
|
|
.debug_struct("crate::version::Version")
|
|
.field("minor", &self.minor)
|
|
.field("patch", &self.patch)
|
|
.field("channel", &self.channel)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl Debug for Channel {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
Channel::Stable => formatter.write_str("crate::version::Channel::Stable"),
|
|
Channel::Beta => formatter.write_str("crate::version::Channel::Beta"),
|
|
Channel::Nightly(date) => formatter
|
|
.debug_tuple("crate::version::Channel::Nightly")
|
|
.field(date)
|
|
.finish(),
|
|
Channel::Dev => formatter.write_str("crate::version::Channel::Dev"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Debug for Date {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
formatter
|
|
.debug_struct("crate::date::Date")
|
|
.field("year", &self.year)
|
|
.field("month", &self.month)
|
|
.field("day", &self.day)
|
|
.finish()
|
|
}
|
|
}
|