Skip to main content

alopex_cli/version/
compatibility.rs

1use super::{cli_version, supported_format_max, supported_format_min, Version};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum VersionCheckResult {
5    Compatible,
6    CliOlderThanFile { cli: Version, file: Version },
7    Incompatible { cli: Version, file: Version },
8}
9
10pub struct VersionChecker {
11    cli_version: Version,
12    supported_format_min: Version,
13    supported_format_max: Version,
14}
15
16impl VersionChecker {
17    pub fn new() -> Self {
18        Self {
19            cli_version: cli_version(),
20            supported_format_min: supported_format_min(),
21            supported_format_max: supported_format_max(),
22        }
23    }
24
25    #[cfg(test)]
26    pub(crate) fn new_with(cli_version: Version, min: Version, max: Version) -> Self {
27        Self {
28            cli_version,
29            supported_format_min: min,
30            supported_format_max: max,
31        }
32    }
33
34    pub fn check_compatibility(&self, file_format_version: Version) -> VersionCheckResult {
35        if file_format_version < self.supported_format_min
36            || file_format_version > self.supported_format_max
37        {
38            return VersionCheckResult::Incompatible {
39                cli: self.cli_version,
40                file: file_format_version,
41            };
42        }
43
44        if file_format_version > self.cli_version {
45            return VersionCheckResult::CliOlderThanFile {
46                cli: self.cli_version,
47                file: file_format_version,
48            };
49        }
50
51        VersionCheckResult::Compatible
52    }
53}
54
55impl Default for VersionChecker {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    fn checker(cli: Version, min: Version, max: Version) -> VersionChecker {
66        VersionChecker::new_with(cli, min, max)
67    }
68
69    #[test]
70    fn compatible_when_file_in_range_and_not_newer() {
71        let checker = checker(
72            Version::new(1, 2, 0),
73            Version::new(1, 0, 0),
74            Version::new(2, 0, 0),
75        );
76        let result = checker.check_compatibility(Version::new(1, 1, 0));
77        assert!(matches!(result, VersionCheckResult::Compatible));
78    }
79
80    #[test]
81    fn warns_when_file_is_newer_but_supported() {
82        let checker = checker(
83            Version::new(1, 0, 0),
84            Version::new(1, 0, 0),
85            Version::new(2, 0, 0),
86        );
87        let result = checker.check_compatibility(Version::new(1, 5, 0));
88        assert!(matches!(
89            result,
90            VersionCheckResult::CliOlderThanFile { .. }
91        ));
92    }
93
94    #[test]
95    fn incompatible_when_file_too_new() {
96        let checker = checker(
97            Version::new(1, 0, 0),
98            Version::new(1, 0, 0),
99            Version::new(1, 2, 0),
100        );
101        let result = checker.check_compatibility(Version::new(2, 0, 0));
102        assert!(matches!(result, VersionCheckResult::Incompatible { .. }));
103    }
104
105    #[test]
106    fn incompatible_when_file_too_old() {
107        let checker = checker(
108            Version::new(1, 0, 0),
109            Version::new(1, 0, 0),
110            Version::new(2, 0, 0),
111        );
112        let result = checker.check_compatibility(Version::new(0, 9, 0));
113        assert!(matches!(result, VersionCheckResult::Incompatible { .. }));
114    }
115}