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}