1use crate::channel::Channel;
2use crate::parser::Rule;
3use crate::parser::VersionParser;
4
5#[derive(Debug, PartialEq, Clone, Copy)]
7pub enum Version {
8 FullStable(usize, usize, usize),
10 MajorMinor(usize, usize),
12 MajorOnly(usize),
14 NonStable(usize, usize, usize, usize, usize, Channel),
16}
17
18impl Version {
19 pub fn parse<S: AsRef<str>>(s: S) -> Result<Version, Box<pest::error::Error<Rule>>> {
21 VersionParser::version(s.as_ref())
22 }
23 pub fn is_stable(&self) -> bool {
25 !matches!(self, Self::NonStable(..))
26 }
27
28 pub fn channel(&self) -> Channel {
30 match self {
31 Self::NonStable(.., c) => *c,
32 _ => Channel::Stable,
33 }
34 }
35
36 pub fn as_string(&self) -> String {
38 match self {
39 Self::MajorOnly(major) => format!("v{major}"),
40 Self::MajorMinor(major, minor) => format!("v{major}.{minor}"),
41 Self::FullStable(major, minor, patch) => format!("v{major}.{minor}.{patch}"),
42 Self::NonStable(ma, mi, pa, pr, prp, c) => {
43 format!("v{ma}.{mi}.{pa}-{pr}.{prp}.{c}")
44 }
45 }
46 }
47}
48
49impl std::str::FromStr for Version {
50 type Err = Box<pest::error::Error<Rule>>;
51
52 fn from_str(s: &str) -> Result<Self, Self::Err> {
53 Version::parse(s)
54 }
55}
56
57impl std::fmt::Display for Version {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "{}", self.as_string())
60 }
61}
62
63impl std::default::Default for Version {
64 fn default() -> Self {
65 Version::MajorOnly(0)
66 }
67}
68
69#[cfg(test)]
70mod test {
71 use super::*;
72
73 #[test]
74 fn version_test() {
75 assert_eq!(
76 Version::parse("v3.4.5").unwrap(),
77 Version::FullStable(3, 4, 5)
78 );
79 }
80
81 #[test]
82 fn stable_test() {
83 assert!(Version::parse("v3").unwrap().is_stable());
84 assert!(!Version::parse("v3.4.5-1.2.beta").unwrap().is_stable());
85 }
86
87 #[test]
88 fn format_str_test() {
89 assert_eq!(
90 Version::parse("v3.4.5").unwrap().as_string(),
91 String::from("v3.4.5")
92 );
93 assert_eq!(
94 Version::parse("v3.4.5-1.2.dev").unwrap().as_string(),
95 String::from("v3.4.5-1.2.dev")
96 );
97 assert_ne!(
98 Version::parse("v3.4.5-1.2.dev").unwrap().as_string(),
99 String::from("v3.4.5")
100 );
101 }
102}