ver_cmp/
lib.rs

1use std::cmp::Ordering;
2
3mod test;
4
5/// Compares two versions in the format x.y.z and returns the ordering
6pub fn compare_versions(ver1: &str, ver2: &str) -> Result<Ordering, &'static str> {
7    let ver1: Vec<u16> = ver1.split('.').map(|s| s.parse().unwrap()).collect();
8    let ver2: Vec<u16> = ver2.split('.').map(|s| s.parse().unwrap()).collect();
9
10    // Return an error if the versions is not in the format x.y.z
11    if ver1.len() != 3 || ver2.len() != 3 {
12        return Err("Invalid version format");
13    }
14
15    for (v1, v2) in ver1.iter().zip(ver2.iter()) {
16        match v1.cmp(v2) {
17            std::cmp::Ordering::Greater => return Ok(Ordering::Greater),
18            std::cmp::Ordering::Less => return Ok(Ordering::Less),
19            _ => continue,
20        }
21    }
22
23    Ok(Ordering::Equal)
24}
25
26/// Returns the greater of two versions in the x.y.z format
27pub fn greater_ver(ver1: &str, ver2: &str) -> Result<String, &'static str> {
28    let greater = match compare_versions(ver1, ver2) {
29        Ok(Ordering::Greater) => ver1,
30        Ok(Ordering::Less) => ver2,
31        Ok(Ordering::Equal) => ver1,
32        Err(_) => return Err("Unable to compare versions due to invalid version format"),
33    };
34
35    Ok(greater.to_string())
36}
37
38/// Returns the lesser of two versions in the x.y.z format
39pub fn lesser_ver(ver1: &str, ver2: &str) -> Result<String, &'static str> {
40    let lesser = match compare_versions(ver1, ver2) {
41        Ok(Ordering::Greater) => ver2,
42        Ok(Ordering::Less) => ver1,
43        Ok(Ordering::Equal) => ver1,
44        Err(_) => return Err("Unable to compare versions due to invalid version format"),
45    };
46
47    Ok(lesser.to_string())
48}
49
50/// Returns true if the version is between the lower and upper bounds
51pub fn is_ver_between(ver: &str, lower: &str, upper: &str) -> Result<bool, &'static str> {
52    let lower = compare_versions(ver, lower)?;
53    let upper = compare_versions(ver, upper)?;
54
55    if (lower == Ordering::Greater || lower == Ordering::Equal)
56        && (upper == Ordering::Less || upper == Ordering::Equal)
57    {
58        return Ok(true);
59    }
60
61    Ok(false)
62}