version_check/
channel.rs

1use std::fmt;
2
3#[derive(Debug, PartialEq, Eq, Copy, Clone)]
4enum Kind {
5    Dev,
6    Nightly,
7    Beta,
8    Stable,
9}
10
11/// Release channel: "dev", "nightly", "beta", or "stable".
12#[derive(Debug, PartialEq, Eq, Copy, Clone)]
13pub struct Channel(Kind);
14
15impl Channel {
16    /// Reads the release channel of the running compiler. If it cannot be
17    /// determined (see the [top-level documentation](crate)), returns `None`.
18    ///
19    /// # Example
20    ///
21    /// ```rust
22    /// use version_check::Channel;
23    ///
24    /// match Channel::read() {
25    ///     Some(c) => format!("The channel is: {}", c),
26    ///     None => format!("Failed to read the release channel.")
27    /// };
28    /// ```
29    pub fn read() -> Option<Channel> {
30        ::get_version_and_date()
31            .and_then(|(version, _)| version)
32            .and_then(|version| Channel::parse(&version))
33    }
34
35    /// Parse a Rust release channel from a Rust release version string (of the
36    /// form `major[.minor[.patch[-channel]]]`). Returns `None` if `version` is
37    /// not a valid Rust version string.
38    ///
39    /// # Example
40    ///
41    /// ```rust
42    /// use version_check::Channel;
43    ///
44    /// let dev = Channel::parse("1.3.0-dev").unwrap();
45    /// assert!(dev.is_dev());
46    ///
47    /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
48    /// assert!(nightly.is_nightly());
49    ///
50    /// let beta = Channel::parse("1.32.0-beta").unwrap();
51    /// assert!(beta.is_beta());
52    ///
53    /// let stable = Channel::parse("1.4.0").unwrap();
54    /// assert!(stable.is_stable());
55    /// ```
56    pub fn parse(version: &str) -> Option<Channel> {
57        let version = version.trim();
58        if version.contains("-dev") || version == "dev" {
59            Some(Channel(Kind::Dev))
60        } else if version.contains("-nightly") || version == "nightly" {
61            Some(Channel(Kind::Nightly))
62        } else if version.contains("-beta") || version == "beta" {
63            Some(Channel(Kind::Beta))
64        } else if !version.contains("-") {
65            Some(Channel(Kind::Stable))
66        } else {
67            None
68        }
69    }
70
71    /// Returns the name of the release channel.
72    fn as_str(&self) -> &'static str {
73        match self.0 {
74            Kind::Dev => "dev",
75            Kind::Beta => "beta",
76            Kind::Nightly => "nightly",
77            Kind::Stable => "stable",
78        }
79    }
80
81    /// Returns `true` if this channel supports feature flags. In other words,
82    /// returns `true` if the channel is either `dev` or `nightly`.
83    ///
84    /// **Please see the note on [feature detection](crate#feature-detection).**
85    ///
86    /// # Example
87    ///
88    /// ```rust
89    /// use version_check::Channel;
90    ///
91    /// let dev = Channel::parse("1.3.0-dev").unwrap();
92    /// assert!(dev.supports_features());
93    ///
94    /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
95    /// assert!(nightly.supports_features());
96    ///
97    /// let beta = Channel::parse("1.32.0-beta").unwrap();
98    /// assert!(!beta.supports_features());
99    ///
100    /// let stable = Channel::parse("1.4.0").unwrap();
101    /// assert!(!stable.supports_features());
102    /// ```
103    pub fn supports_features(&self) -> bool {
104        match self.0 {
105            Kind::Dev | Kind::Nightly => true,
106            Kind::Beta | Kind::Stable => false
107        }
108    }
109
110    /// Returns `true` if this channel is `dev` and `false` otherwise.
111    ///
112    /// # Example
113    ///
114    /// ```rust
115    /// use version_check::Channel;
116    ///
117    /// let dev = Channel::parse("1.3.0-dev").unwrap();
118    /// assert!(dev.is_dev());
119    ///
120    /// let stable = Channel::parse("1.0.0").unwrap();
121    /// assert!(!stable.is_dev());
122    /// ```
123    pub fn is_dev(&self) -> bool {
124        match self.0 {
125            Kind::Dev => true,
126            _ => false
127        }
128    }
129
130    /// Returns `true` if this channel is `nightly` and `false` otherwise.
131    ///
132    /// # Example
133    ///
134    /// ```rust
135    /// use version_check::Channel;
136    ///
137    /// let nightly = Channel::parse("1.3.0-nightly").unwrap();
138    /// assert!(nightly.is_nightly());
139    ///
140    /// let stable = Channel::parse("1.0.0").unwrap();
141    /// assert!(!stable.is_nightly());
142    /// ```
143    pub fn is_nightly(&self) -> bool {
144        match self.0 {
145            Kind::Nightly => true,
146            _ => false
147        }
148    }
149
150    /// Returns `true` if this channel is `beta` and `false` otherwise.
151    ///
152    /// # Example
153    ///
154    /// ```rust
155    /// use version_check::Channel;
156    ///
157    /// let beta = Channel::parse("1.3.0-beta").unwrap();
158    /// assert!(beta.is_beta());
159    ///
160    /// let stable = Channel::parse("1.0.0").unwrap();
161    /// assert!(!stable.is_beta());
162    /// ```
163    pub fn is_beta(&self) -> bool {
164        match self.0 {
165            Kind::Beta => true,
166            _ => false
167        }
168    }
169
170    /// Returns `true` if this channel is `stable` and `false` otherwise.
171    ///
172    /// # Example
173    ///
174    /// ```rust
175    /// use version_check::Channel;
176    ///
177    /// let stable = Channel::parse("1.0.0").unwrap();
178    /// assert!(stable.is_stable());
179    ///
180    /// let beta = Channel::parse("1.3.0-beta").unwrap();
181    /// assert!(!beta.is_stable());
182    /// ```
183    pub fn is_stable(&self) -> bool {
184        match self.0 {
185            Kind::Stable => true,
186            _ => false
187        }
188    }
189}
190
191impl fmt::Display for Channel {
192    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
193        write!(f, "{}", self.as_str())
194    }
195}