alopex_cli/version/
mod.rs1use std::fmt;
2
3use alopex_core::storage::format::FileVersion;
4
5pub mod compatibility;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
8pub struct Version {
9 pub major: u16,
10 pub minor: u16,
11 pub patch: u16,
12}
13
14impl Version {
15 pub const fn new(major: u16, minor: u16, patch: u16) -> Self {
16 Self {
17 major,
18 minor,
19 patch,
20 }
21 }
22
23 pub fn parse(raw: &str) -> Self {
24 let mut parts = raw.split('.');
25 let major = parse_part(parts.next());
26 let minor = parse_part(parts.next());
27 let patch = parse_part(parts.next());
28 Self {
29 major,
30 minor,
31 patch,
32 }
33 }
34}
35
36impl From<FileVersion> for Version {
37 fn from(value: FileVersion) -> Self {
38 Self::new(value.major, value.minor, value.patch)
39 }
40}
41
42impl fmt::Display for Version {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
45 }
46}
47
48pub fn cli_version() -> Version {
49 Version::parse(env!("CARGO_PKG_VERSION"))
50}
51
52pub fn supported_format_min() -> Version {
53 Version::new(0, 1, 0)
54}
55
56pub fn supported_format_max() -> Version {
57 Version::from(FileVersion::CURRENT)
58}
59
60fn parse_part(part: Option<&str>) -> u16 {
61 part.and_then(|value| {
62 let digits: String = value.chars().take_while(|c| c.is_ascii_digit()).collect();
63 if digits.is_empty() {
64 None
65 } else {
66 digits.parse::<u16>().ok()
67 }
68 })
69 .unwrap_or(0)
70}