mc_core/util/
version.rs

1use std::fmt::{Display, Formatter, Result as FmtResult};
2use std::str::FromStr;
3
4
5#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd)]
6pub enum VersionType {
7    Release,
8    Beta,
9    Alpha
10}
11
12use VersionType::*;
13
14impl VersionType {
15    fn prefix(self) -> &'static str {
16        match self {
17            Alpha => "a",
18            Beta => "b",
19            Release => ""
20        }
21    }
22}
23
24
25/// A version struct tuple used to represent common versions from alpha.
26///
27/// Pre-release and release candidate are not yet representable with this.
28///
29/// The numbers are in the order: major version (always 1 for now),
30/// minor version, patch version.
31#[derive(Debug, Eq, PartialEq, Copy, Clone, Ord, PartialOrd)]
32pub struct Version(pub VersionType, pub u16, pub u16, pub u16);
33
34
35impl Version {
36
37    pub const RELEASE_1_3_2: Version = Version(Release, 1, 3, 2);
38    pub const RELEASE_1_3_1: Version = Version(Release, 1, 3, 1);
39    pub const RELEASE_1_3: Version   = Version(Release, 1, 3, 0);
40
41    pub const RELEASE_1_2_5: Version = Version(Release, 1, 2, 5);
42    pub const RELEASE_1_2_4: Version = Version(Release, 1, 2, 4);
43    pub const RELEASE_1_2_3: Version = Version(Release, 1, 2, 3);
44    pub const RELEASE_1_2_2: Version = Version(Release, 1, 2, 2);
45    pub const RELEASE_1_2_1: Version = Version(Release, 1, 2, 1);
46    pub const RELEASE_1_2: Version = Version(Release, 1, 2, 0);
47
48    pub fn version_type(&self) -> VersionType { self.0 }
49    pub fn major(&self) -> u16 { self.1 }
50    pub fn minor(&self) -> u16 { self.2 }
51    pub fn patch(&self) -> u16 { self.3 }
52
53}
54
55
56impl FromStr for Version {
57
58    type Err = String;
59
60    fn from_str(s: &str) -> Result<Self, Self::Err> {
61
62        if s.is_empty() {
63            return Err("Empty version".to_string());
64        }
65
66        let (version_type, s) = match &s[0..1] {
67            "a" => (Alpha, &s[1..]),
68            "b" => (Beta, &s[1..]),
69            _ => (Release, s)
70        };
71
72        let mut v = Version(version_type, 0, 0, 0);
73
74        for (i, part) in s.split(".").enumerate().take(3) {
75            match part.parse::<u16>() {
76                Ok(num) => match i {
77                    0 => v.1 = num,
78                    1 => v.2 = num,
79                    2 => v.3 = num,
80                    _ => {}
81                }
82                Err(e) => return Err(format!("Failed to parse part {} '{}': {}", i, part, e))
83            }
84        }
85
86        Ok(v)
87
88    }
89
90}
91
92impl Display for Version {
93    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
94        f.write_str(self.0.prefix())?;
95        f.write_fmt(format_args!("{}.{}", self.1, self.2))?;
96        if self.2 != 0 {
97            f.write_fmt(format_args!(".{}", self.3))?;
98        }
99        Ok(())
100    }
101}