alopex_cli/version/
compatibility.rs1use 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}