summaryrefslogtreecommitdiffstats
path: root/vendor/os_info/src/version.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/os_info/src/version.rs')
-rw-r--r--vendor/os_info/src/version.rs150
1 files changed, 150 insertions, 0 deletions
diff --git a/vendor/os_info/src/version.rs b/vendor/os_info/src/version.rs
new file mode 100644
index 000000000..20a2c4a61
--- /dev/null
+++ b/vendor/os_info/src/version.rs
@@ -0,0 +1,150 @@
+use std::fmt::{self, Display, Formatter};
+
+#[cfg(feature = "serde")]
+use serde::{Deserialize, Serialize};
+
+/// Operating system version.
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+pub enum Version {
+ /// Unknown version.
+ Unknown,
+ /// Semantic version (major.minor.patch).
+ Semantic(u64, u64, u64),
+ /// Rolling version. Optionally contains the release date in the string format.
+ Rolling(Option<String>),
+ /// Custom version format.
+ Custom(String),
+}
+
+impl Version {
+ /// Constructs `VersionType` from the given string.
+ ///
+ /// Returns `VersionType::Unknown` if the string is empty. If it can be parsed as a semantic
+ /// version, then `VersionType::Semantic`, otherwise `VersionType::Custom`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use os_info::Version;
+ ///
+ /// let v = Version::from_string("custom");
+ /// assert_eq!(Version::Custom("custom".to_owned()), v);
+ ///
+ /// let v = Version::from_string("1.2.3");
+ /// assert_eq!(Version::Semantic(1, 2, 3), v);
+ /// ```
+ pub fn from_string<S: Into<String> + AsRef<str>>(s: S) -> Self {
+ if s.as_ref().is_empty() {
+ Self::Unknown
+ } else if let Some((major, minor, patch)) = parse_version(s.as_ref()) {
+ Self::Semantic(major, minor, patch)
+ } else {
+ Self::Custom(s.into())
+ }
+ }
+}
+
+impl Default for Version {
+ fn default() -> Self {
+ Version::Unknown
+ }
+}
+
+impl Display for Version {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ match *self {
+ Self::Unknown => f.write_str("Unknown"),
+ Self::Semantic(major, minor, patch) => write!(f, "{}.{}.{}", major, minor, patch),
+ Self::Rolling(ref date) => {
+ let date = match date {
+ Some(date) => format!(" ({})", date),
+ None => "".to_owned(),
+ };
+ write!(f, "Rolling Release{}", date)
+ }
+ Self::Custom(ref version) => write!(f, "{}", version),
+ }
+ }
+}
+
+fn parse_version(s: &str) -> Option<(u64, u64, u64)> {
+ let mut iter = s.trim().split_terminator('.').fuse();
+
+ let major = iter.next().and_then(|s| s.parse().ok())?;
+ let minor = iter.next().unwrap_or("0").parse().ok()?;
+ let patch = iter.next().unwrap_or("0").parse().ok()?;
+
+ if iter.next().is_some() {
+ return None;
+ }
+
+ Some((major, minor, patch))
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use pretty_assertions::assert_eq;
+
+ #[test]
+ fn parse_semantic_version() {
+ let data = [
+ ("", None),
+ ("version", None),
+ ("1", Some((1, 0, 0))),
+ ("1.", Some((1, 0, 0))),
+ ("1.2", Some((1, 2, 0))),
+ ("1.2.", Some((1, 2, 0))),
+ ("1.2.3", Some((1, 2, 3))),
+ ("1.2.3.", Some((1, 2, 3))),
+ ("1.2.3. ", Some((1, 2, 3))),
+ (" 1.2.3.", Some((1, 2, 3))),
+ (" 1.2.3. ", Some((1, 2, 3))),
+ ("1.2.3.4", None),
+ ("1.2.3.4.5.6.7.8.9", None),
+ ];
+
+ for (s, expected) in &data {
+ let result = parse_version(s);
+ assert_eq!(expected, &result);
+ }
+ }
+
+ #[test]
+ fn from_string() {
+ let custom_version = "some version";
+ let data = [
+ ("", Version::Unknown),
+ ("1.2.3", Version::Semantic(1, 2, 3)),
+ (custom_version, Version::Custom(custom_version.to_owned())),
+ ];
+
+ for (s, expected) in &data {
+ let version = Version::from_string(*s);
+ assert_eq!(expected, &version);
+ }
+ }
+
+ #[test]
+ fn default() {
+ assert_eq!(Version::Unknown, Version::default());
+ }
+
+ #[test]
+ fn display() {
+ let data = [
+ (Version::Unknown, "Unknown"),
+ (Version::Semantic(1, 5, 0), "1.5.0"),
+ (Version::Rolling(None), "Rolling Release"),
+ (
+ Version::Rolling(Some("date".to_owned())),
+ "Rolling Release (date)",
+ ),
+ ];
+
+ for (version, expected) in &data {
+ assert_eq!(expected, &version.to_string());
+ }
+ }
+}