version_compare/
compare.rs

1//! Version compare module, with useful static comparison methods.
2
3use crate::version::Version;
4use crate::Cmp;
5
6/// Compare two version number strings to each other.
7///
8/// This compares version `a` to version `b`, and returns whether version `a` is greater, less
9/// or equal to version `b`.
10///
11/// If either version number string is invalid an error is returned.
12///
13/// One of the following operators is returned:
14///
15/// * `Cmp::Eq`
16/// * `Cmp::Lt`
17/// * `Cmp::Gt`
18///
19/// # Examples
20///
21/// ```
22/// use version_compare::{Cmp, compare};
23///
24/// assert_eq!(compare("1.2.3", "1.2.3"), Ok(Cmp::Eq));
25/// assert_eq!(compare("1.2.3", "1.2.4"), Ok(Cmp::Lt));
26/// assert_eq!(compare("1", "0.1"), Ok(Cmp::Gt));
27/// ```
28#[allow(clippy::result_unit_err)]
29pub fn compare<A, B>(a: A, b: B) -> Result<Cmp, ()>
30where
31    A: AsRef<str>,
32    B: AsRef<str>,
33{
34    let a = Version::from(a.as_ref()).ok_or(())?;
35    let b = Version::from(b.as_ref()).ok_or(())?;
36    Ok(a.compare(b))
37}
38
39/// Compare two version number strings to each other and test against the given comparison
40/// `operator`.
41///
42/// If either version number string is invalid an error is returned.
43///
44/// # Examples
45///
46/// ```
47/// use version_compare::{Cmp, compare_to};
48///
49/// assert!(compare_to("1.2.3", "1.2.3", Cmp::Eq).unwrap());
50/// assert!(compare_to("1.2.3", "1.2.3", Cmp::Le).unwrap());
51/// assert!(compare_to("1.2.3", "1.2.4", Cmp::Lt).unwrap());
52/// assert!(compare_to("1", "0.1", Cmp::Gt).unwrap());
53/// assert!(compare_to("1", "0.1", Cmp::Ge).unwrap());
54/// ```
55#[allow(clippy::result_unit_err)]
56pub fn compare_to<A, B>(a: A, b: B, operator: Cmp) -> Result<bool, ()>
57where
58    A: AsRef<str>,
59    B: AsRef<str>,
60{
61    let a = Version::from(a.as_ref()).ok_or(())?;
62    let b = Version::from(b.as_ref()).ok_or(())?;
63    Ok(a.compare_to(b, operator))
64}
65
66#[cfg_attr(tarpaulin, skip)]
67#[cfg(test)]
68mod tests {
69    use crate::test::{COMBIS, COMBIS_ERROR};
70    use crate::Cmp;
71
72    #[test]
73    fn compare() {
74        // Compare each version in the version set having the default manifest
75        for entry in COMBIS.iter().filter(|c| c.3.is_none()) {
76            assert_eq!(
77                super::compare(entry.0, entry.1),
78                Ok(entry.2),
79                "Testing that {} is {} {}",
80                entry.0,
81                entry.2.sign(),
82                entry.1,
83            );
84        }
85
86        // Compare each error version in the version set
87        for entry in COMBIS_ERROR {
88            let result = super::compare(entry.0, entry.1);
89
90            if result.is_ok() {
91                assert!(result != Ok(entry.2));
92            }
93        }
94    }
95
96    #[test]
97    fn compare_to() {
98        // Compare each version in the version set having the default manifest
99        for entry in COMBIS.iter().filter(|c| c.3.is_none()) {
100            // Test
101            assert!(super::compare_to(entry.0, entry.1, entry.2).unwrap());
102
103            // Make sure the inverse operator is not correct
104            assert!(!super::compare_to(entry.0, entry.1, entry.2.invert()).unwrap());
105        }
106
107        // Compare each error version in the version set
108        for entry in COMBIS_ERROR {
109            let result = super::compare_to(entry.0, entry.1, entry.2);
110
111            if result.is_ok() {
112                assert!(!result.unwrap())
113            }
114        }
115
116        // Assert an exceptional case, compare to not equal
117        assert!(super::compare_to("1.2.3", "1.2", Cmp::Ne).unwrap());
118    }
119}