16acc7838Sopenharmony_ciuse std::fmt;
26acc7838Sopenharmony_ci
36acc7838Sopenharmony_ci#[derive(Debug, PartialEq, Eq, Copy, Clone)]
46acc7838Sopenharmony_cienum Kind {
56acc7838Sopenharmony_ci    Dev,
66acc7838Sopenharmony_ci    Nightly,
76acc7838Sopenharmony_ci    Beta,
86acc7838Sopenharmony_ci    Stable,
96acc7838Sopenharmony_ci}
106acc7838Sopenharmony_ci
116acc7838Sopenharmony_ci/// Release channel: "dev", "nightly", "beta", or "stable".
126acc7838Sopenharmony_ci#[derive(Debug, PartialEq, Eq, Copy, Clone)]
136acc7838Sopenharmony_cipub struct Channel(Kind);
146acc7838Sopenharmony_ci
156acc7838Sopenharmony_ciimpl Channel {
166acc7838Sopenharmony_ci    /// Reads the release channel of the running compiler. If it cannot be
176acc7838Sopenharmony_ci    /// determined (see the [top-level documentation](crate)), returns `None`.
186acc7838Sopenharmony_ci    ///
196acc7838Sopenharmony_ci    /// # Example
206acc7838Sopenharmony_ci    ///
216acc7838Sopenharmony_ci    /// ```rust
226acc7838Sopenharmony_ci    /// use version_check::Channel;
236acc7838Sopenharmony_ci    ///
246acc7838Sopenharmony_ci    /// match Channel::read() {
256acc7838Sopenharmony_ci    ///     Some(c) => format!("The channel is: {}", c),
266acc7838Sopenharmony_ci    ///     None => format!("Failed to read the release channel.")
276acc7838Sopenharmony_ci    /// };
286acc7838Sopenharmony_ci    /// ```
296acc7838Sopenharmony_ci    pub fn read() -> Option<Channel> {
306acc7838Sopenharmony_ci        ::get_version_and_date()
316acc7838Sopenharmony_ci            .and_then(|(version, _)| version)
326acc7838Sopenharmony_ci            .and_then(|version| Channel::parse(&version))
336acc7838Sopenharmony_ci    }
346acc7838Sopenharmony_ci
356acc7838Sopenharmony_ci    /// Parse a Rust release channel from a Rust release version string (of the
366acc7838Sopenharmony_ci    /// form `major[.minor[.patch[-channel]]]`). Returns `None` if `version` is
376acc7838Sopenharmony_ci    /// not a valid Rust version string.
386acc7838Sopenharmony_ci    ///
396acc7838Sopenharmony_ci    /// # Example
406acc7838Sopenharmony_ci    ///
416acc7838Sopenharmony_ci    /// ```rust
426acc7838Sopenharmony_ci    /// use version_check::Channel;
436acc7838Sopenharmony_ci    ///
446acc7838Sopenharmony_ci    /// let dev = Channel::parse("1.3.0-dev").unwrap();
456acc7838Sopenharmony_ci    /// assert!(dev.is_dev());
466acc7838Sopenharmony_ci    ///
476acc7838Sopenharmony_ci    /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
486acc7838Sopenharmony_ci    /// assert!(nightly.is_nightly());
496acc7838Sopenharmony_ci    ///
506acc7838Sopenharmony_ci    /// let beta = Channel::parse("1.32.0-beta").unwrap();
516acc7838Sopenharmony_ci    /// assert!(beta.is_beta());
526acc7838Sopenharmony_ci    ///
536acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.4.0").unwrap();
546acc7838Sopenharmony_ci    /// assert!(stable.is_stable());
556acc7838Sopenharmony_ci    /// ```
566acc7838Sopenharmony_ci    pub fn parse(version: &str) -> Option<Channel> {
576acc7838Sopenharmony_ci        let version = version.trim();
586acc7838Sopenharmony_ci        if version.contains("-dev") || version == "dev" {
596acc7838Sopenharmony_ci            Some(Channel(Kind::Dev))
606acc7838Sopenharmony_ci        } else if version.contains("-nightly") || version == "nightly" {
616acc7838Sopenharmony_ci            Some(Channel(Kind::Nightly))
626acc7838Sopenharmony_ci        } else if version.contains("-beta") || version == "beta" {
636acc7838Sopenharmony_ci            Some(Channel(Kind::Beta))
646acc7838Sopenharmony_ci        } else if !version.contains("-") {
656acc7838Sopenharmony_ci            Some(Channel(Kind::Stable))
666acc7838Sopenharmony_ci        } else {
676acc7838Sopenharmony_ci            None
686acc7838Sopenharmony_ci        }
696acc7838Sopenharmony_ci    }
706acc7838Sopenharmony_ci
716acc7838Sopenharmony_ci    /// Returns the name of the release channel.
726acc7838Sopenharmony_ci    fn as_str(&self) -> &'static str {
736acc7838Sopenharmony_ci        match self.0 {
746acc7838Sopenharmony_ci            Kind::Dev => "dev",
756acc7838Sopenharmony_ci            Kind::Beta => "beta",
766acc7838Sopenharmony_ci            Kind::Nightly => "nightly",
776acc7838Sopenharmony_ci            Kind::Stable => "stable",
786acc7838Sopenharmony_ci        }
796acc7838Sopenharmony_ci    }
806acc7838Sopenharmony_ci
816acc7838Sopenharmony_ci    /// Returns `true` if this channel supports feature flags. In other words,
826acc7838Sopenharmony_ci    /// returns `true` if the channel is either `dev` or `nightly`.
836acc7838Sopenharmony_ci    ///
846acc7838Sopenharmony_ci    /// # Example
856acc7838Sopenharmony_ci    ///
866acc7838Sopenharmony_ci    /// ```rust
876acc7838Sopenharmony_ci    /// use version_check::Channel;
886acc7838Sopenharmony_ci    ///
896acc7838Sopenharmony_ci    /// let dev = Channel::parse("1.3.0-dev").unwrap();
906acc7838Sopenharmony_ci    /// assert!(dev.supports_features());
916acc7838Sopenharmony_ci    ///
926acc7838Sopenharmony_ci    /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
936acc7838Sopenharmony_ci    /// assert!(nightly.supports_features());
946acc7838Sopenharmony_ci    ///
956acc7838Sopenharmony_ci    /// let beta = Channel::parse("1.32.0-beta").unwrap();
966acc7838Sopenharmony_ci    /// assert!(!beta.supports_features());
976acc7838Sopenharmony_ci    ///
986acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.4.0").unwrap();
996acc7838Sopenharmony_ci    /// assert!(!stable.supports_features());
1006acc7838Sopenharmony_ci    /// ```
1016acc7838Sopenharmony_ci    pub fn supports_features(&self) -> bool {
1026acc7838Sopenharmony_ci        match self.0 {
1036acc7838Sopenharmony_ci            Kind::Dev | Kind::Nightly => true,
1046acc7838Sopenharmony_ci            Kind::Beta | Kind::Stable => false
1056acc7838Sopenharmony_ci        }
1066acc7838Sopenharmony_ci    }
1076acc7838Sopenharmony_ci
1086acc7838Sopenharmony_ci    /// Returns `true` if this channel is `dev` and `false` otherwise.
1096acc7838Sopenharmony_ci    ///
1106acc7838Sopenharmony_ci    /// # Example
1116acc7838Sopenharmony_ci    ///
1126acc7838Sopenharmony_ci    /// ```rust
1136acc7838Sopenharmony_ci    /// use version_check::Channel;
1146acc7838Sopenharmony_ci    ///
1156acc7838Sopenharmony_ci    /// let dev = Channel::parse("1.3.0-dev").unwrap();
1166acc7838Sopenharmony_ci    /// assert!(dev.is_dev());
1176acc7838Sopenharmony_ci    ///
1186acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.0.0").unwrap();
1196acc7838Sopenharmony_ci    /// assert!(!stable.is_dev());
1206acc7838Sopenharmony_ci    /// ```
1216acc7838Sopenharmony_ci    pub fn is_dev(&self) -> bool {
1226acc7838Sopenharmony_ci        match self.0 {
1236acc7838Sopenharmony_ci            Kind::Dev => true,
1246acc7838Sopenharmony_ci            _ => false
1256acc7838Sopenharmony_ci        }
1266acc7838Sopenharmony_ci    }
1276acc7838Sopenharmony_ci
1286acc7838Sopenharmony_ci    /// Returns `true` if this channel is `nightly` and `false` otherwise.
1296acc7838Sopenharmony_ci    ///
1306acc7838Sopenharmony_ci    /// # Example
1316acc7838Sopenharmony_ci    ///
1326acc7838Sopenharmony_ci    /// ```rust
1336acc7838Sopenharmony_ci    /// use version_check::Channel;
1346acc7838Sopenharmony_ci    ///
1356acc7838Sopenharmony_ci    /// let nightly = Channel::parse("1.3.0-nightly").unwrap();
1366acc7838Sopenharmony_ci    /// assert!(nightly.is_nightly());
1376acc7838Sopenharmony_ci    ///
1386acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.0.0").unwrap();
1396acc7838Sopenharmony_ci    /// assert!(!stable.is_nightly());
1406acc7838Sopenharmony_ci    /// ```
1416acc7838Sopenharmony_ci    pub fn is_nightly(&self) -> bool {
1426acc7838Sopenharmony_ci        match self.0 {
1436acc7838Sopenharmony_ci            Kind::Nightly => true,
1446acc7838Sopenharmony_ci            _ => false
1456acc7838Sopenharmony_ci        }
1466acc7838Sopenharmony_ci    }
1476acc7838Sopenharmony_ci
1486acc7838Sopenharmony_ci    /// Returns `true` if this channel is `beta` and `false` otherwise.
1496acc7838Sopenharmony_ci    ///
1506acc7838Sopenharmony_ci    /// # Example
1516acc7838Sopenharmony_ci    ///
1526acc7838Sopenharmony_ci    /// ```rust
1536acc7838Sopenharmony_ci    /// use version_check::Channel;
1546acc7838Sopenharmony_ci    ///
1556acc7838Sopenharmony_ci    /// let beta = Channel::parse("1.3.0-beta").unwrap();
1566acc7838Sopenharmony_ci    /// assert!(beta.is_beta());
1576acc7838Sopenharmony_ci    ///
1586acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.0.0").unwrap();
1596acc7838Sopenharmony_ci    /// assert!(!stable.is_beta());
1606acc7838Sopenharmony_ci    /// ```
1616acc7838Sopenharmony_ci    pub fn is_beta(&self) -> bool {
1626acc7838Sopenharmony_ci        match self.0 {
1636acc7838Sopenharmony_ci            Kind::Beta => true,
1646acc7838Sopenharmony_ci            _ => false
1656acc7838Sopenharmony_ci        }
1666acc7838Sopenharmony_ci    }
1676acc7838Sopenharmony_ci
1686acc7838Sopenharmony_ci    /// Returns `true` if this channel is `stable` and `false` otherwise.
1696acc7838Sopenharmony_ci    ///
1706acc7838Sopenharmony_ci    /// # Example
1716acc7838Sopenharmony_ci    ///
1726acc7838Sopenharmony_ci    /// ```rust
1736acc7838Sopenharmony_ci    /// use version_check::Channel;
1746acc7838Sopenharmony_ci    ///
1756acc7838Sopenharmony_ci    /// let stable = Channel::parse("1.0.0").unwrap();
1766acc7838Sopenharmony_ci    /// assert!(stable.is_stable());
1776acc7838Sopenharmony_ci    ///
1786acc7838Sopenharmony_ci    /// let beta = Channel::parse("1.3.0-beta").unwrap();
1796acc7838Sopenharmony_ci    /// assert!(!beta.is_stable());
1806acc7838Sopenharmony_ci    /// ```
1816acc7838Sopenharmony_ci    pub fn is_stable(&self) -> bool {
1826acc7838Sopenharmony_ci        match self.0 {
1836acc7838Sopenharmony_ci            Kind::Stable => true,
1846acc7838Sopenharmony_ci            _ => false
1856acc7838Sopenharmony_ci        }
1866acc7838Sopenharmony_ci    }
1876acc7838Sopenharmony_ci}
1886acc7838Sopenharmony_ci
1896acc7838Sopenharmony_ciimpl fmt::Display for Channel {
1906acc7838Sopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1916acc7838Sopenharmony_ci        write!(f, "{}", self.as_str())
1926acc7838Sopenharmony_ci    }
1936acc7838Sopenharmony_ci}
194