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