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#[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}