1 use std::fmt;
2 
3 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
4 enum 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)]
13 pub struct Channel(Kind);
14 
15 impl 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     /// ```
read() -> Option<Channel>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     /// ```
parse(version: &str) -> Option<Channel>56     pub fn parse(version: &str) -> Option<Channel> {
57         if version.contains("-dev") {
58             Some(Channel(Kind::Dev))
59         } else if version.contains("-nightly") {
60             Some(Channel(Kind::Nightly))
61         } else if version.contains("-beta") {
62             Some(Channel(Kind::Beta))
63         } else if !version.contains("-") {
64             Some(Channel(Kind::Stable))
65         } else {
66             None
67         }
68     }
69 
70     /// Returns the name of the release channel.
as_str(&self) -> &'static str71     fn as_str(&self) -> &'static str {
72         match self.0 {
73             Kind::Dev => "dev",
74             Kind::Beta => "beta",
75             Kind::Nightly => "nightly",
76             Kind::Stable => "stable",
77         }
78     }
79 
80     /// Returns `true` if this channel supports feature flags. In other words,
81     /// returns `true` if the channel is either `dev` or `nightly`.
82     ///
83     /// # Example
84     ///
85     /// ```rust
86     /// use version_check::Channel;
87     ///
88     /// let dev = Channel::parse("1.3.0-dev").unwrap();
89     /// assert!(dev.supports_features());
90     ///
91     /// let nightly = Channel::parse("1.42.2-nightly").unwrap();
92     /// assert!(nightly.supports_features());
93     ///
94     /// let beta = Channel::parse("1.32.0-beta").unwrap();
95     /// assert!(!beta.supports_features());
96     ///
97     /// let stable = Channel::parse("1.4.0").unwrap();
98     /// assert!(!stable.supports_features());
99     /// ```
supports_features(&self) -> bool100     pub fn supports_features(&self) -> bool {
101         match self.0 {
102             Kind::Dev | Kind::Nightly => true,
103             Kind::Beta | Kind::Stable => false
104         }
105     }
106 
107     /// Returns `true` if this channel is `dev` and `false` otherwise.
108     ///
109     /// # Example
110     ///
111     /// ```rust
112     /// use version_check::Channel;
113     ///
114     /// let dev = Channel::parse("1.3.0-dev").unwrap();
115     /// assert!(dev.is_dev());
116     ///
117     /// let stable = Channel::parse("1.0.0").unwrap();
118     /// assert!(!stable.is_dev());
119     /// ```
is_dev(&self) -> bool120     pub fn is_dev(&self) -> bool {
121         match self.0 {
122             Kind::Dev => true,
123             _ => false
124         }
125     }
126 
127     /// Returns `true` if this channel is `nightly` and `false` otherwise.
128     ///
129     /// # Example
130     ///
131     /// ```rust
132     /// use version_check::Channel;
133     ///
134     /// let nightly = Channel::parse("1.3.0-nightly").unwrap();
135     /// assert!(nightly.is_nightly());
136     ///
137     /// let stable = Channel::parse("1.0.0").unwrap();
138     /// assert!(!stable.is_nightly());
139     /// ```
is_nightly(&self) -> bool140     pub fn is_nightly(&self) -> bool {
141         match self.0 {
142             Kind::Nightly => true,
143             _ => false
144         }
145     }
146 
147     /// Returns `true` if this channel is `beta` and `false` otherwise.
148     ///
149     /// # Example
150     ///
151     /// ```rust
152     /// use version_check::Channel;
153     ///
154     /// let beta = Channel::parse("1.3.0-beta").unwrap();
155     /// assert!(beta.is_beta());
156     ///
157     /// let stable = Channel::parse("1.0.0").unwrap();
158     /// assert!(!stable.is_beta());
159     /// ```
is_beta(&self) -> bool160     pub fn is_beta(&self) -> bool {
161         match self.0 {
162             Kind::Beta => true,
163             _ => false
164         }
165     }
166 
167     /// Returns `true` if this channel is `stable` and `false` otherwise.
168     ///
169     /// # Example
170     ///
171     /// ```rust
172     /// use version_check::Channel;
173     ///
174     /// let stable = Channel::parse("1.0.0").unwrap();
175     /// assert!(stable.is_stable());
176     ///
177     /// let beta = Channel::parse("1.3.0-beta").unwrap();
178     /// assert!(!beta.is_stable());
179     /// ```
is_stable(&self) -> bool180     pub fn is_stable(&self) -> bool {
181         match self.0 {
182             Kind::Stable => true,
183             _ => false
184         }
185     }
186 }
187 
188 impl fmt::Display for Channel {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result189     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190         write!(f, "{}", self.as_str())
191     }
192 }
193