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 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. as_str(&self) -> &'static str72 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 /// # Example 85 /// 86 /// ```rust 87 /// use version_check::Channel; 88 /// 89 /// let dev = Channel::parse("1.3.0-dev").unwrap(); 90 /// assert!(dev.supports_features()); 91 /// 92 /// let nightly = Channel::parse("1.42.2-nightly").unwrap(); 93 /// assert!(nightly.supports_features()); 94 /// 95 /// let beta = Channel::parse("1.32.0-beta").unwrap(); 96 /// assert!(!beta.supports_features()); 97 /// 98 /// let stable = Channel::parse("1.4.0").unwrap(); 99 /// assert!(!stable.supports_features()); 100 /// ``` supports_features(&self) -> bool101 pub fn supports_features(&self) -> bool { 102 match self.0 { 103 Kind::Dev | Kind::Nightly => true, 104 Kind::Beta | Kind::Stable => false 105 } 106 } 107 108 /// Returns `true` if this channel is `dev` and `false` otherwise. 109 /// 110 /// # Example 111 /// 112 /// ```rust 113 /// use version_check::Channel; 114 /// 115 /// let dev = Channel::parse("1.3.0-dev").unwrap(); 116 /// assert!(dev.is_dev()); 117 /// 118 /// let stable = Channel::parse("1.0.0").unwrap(); 119 /// assert!(!stable.is_dev()); 120 /// ``` is_dev(&self) -> bool121 pub fn is_dev(&self) -> bool { 122 match self.0 { 123 Kind::Dev => true, 124 _ => false 125 } 126 } 127 128 /// Returns `true` if this channel is `nightly` and `false` otherwise. 129 /// 130 /// # Example 131 /// 132 /// ```rust 133 /// use version_check::Channel; 134 /// 135 /// let nightly = Channel::parse("1.3.0-nightly").unwrap(); 136 /// assert!(nightly.is_nightly()); 137 /// 138 /// let stable = Channel::parse("1.0.0").unwrap(); 139 /// assert!(!stable.is_nightly()); 140 /// ``` is_nightly(&self) -> bool141 pub fn is_nightly(&self) -> bool { 142 match self.0 { 143 Kind::Nightly => true, 144 _ => false 145 } 146 } 147 148 /// Returns `true` if this channel is `beta` and `false` otherwise. 149 /// 150 /// # Example 151 /// 152 /// ```rust 153 /// use version_check::Channel; 154 /// 155 /// let beta = Channel::parse("1.3.0-beta").unwrap(); 156 /// assert!(beta.is_beta()); 157 /// 158 /// let stable = Channel::parse("1.0.0").unwrap(); 159 /// assert!(!stable.is_beta()); 160 /// ``` is_beta(&self) -> bool161 pub fn is_beta(&self) -> bool { 162 match self.0 { 163 Kind::Beta => true, 164 _ => false 165 } 166 } 167 168 /// Returns `true` if this channel is `stable` and `false` otherwise. 169 /// 170 /// # Example 171 /// 172 /// ```rust 173 /// use version_check::Channel; 174 /// 175 /// let stable = Channel::parse("1.0.0").unwrap(); 176 /// assert!(stable.is_stable()); 177 /// 178 /// let beta = Channel::parse("1.3.0-beta").unwrap(); 179 /// assert!(!beta.is_stable()); 180 /// ``` is_stable(&self) -> bool181 pub fn is_stable(&self) -> bool { 182 match self.0 { 183 Kind::Stable => true, 184 _ => false 185 } 186 } 187 } 188 189 impl fmt::Display for Channel { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 191 write!(f, "{}", self.as_str()) 192 } 193 } 194