1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
pub mod comp_op;
pub mod version;
pub mod version_part;
#[cfg(test)]
mod test;

use comp_op::CompOp;
use version::Version;

/// Version compare structure.
pub struct VersionCompare { }

/// Version compare implementation.
impl VersionCompare {

    /// Compare two version number strings to each other.
    /// This compares version `a` to version `b`, and returns whether version `a` is greater, less
    /// or equal to version `b`.
    ///
    /// The two given version numbers must be valid, or an error will be returned.
    ///
    /// One of the following ok results may be returned:
    /// - CompOp::Eq
    /// - CompOp::Lt
    /// - CompOp::Gt
    ///
    /// # Examples
    ///
    /// ```
    /// use version_compare::VersionCompare;
    /// use version_compare::comp_op::CompOp;
    ///
    /// // Compare version numbers
    /// assert_eq!(VersionCompare::compare("1.2.3", "1.2.3"), Ok(CompOp::Eq));
    /// assert_eq!(VersionCompare::compare("1.2.3", "1.2.4"), Ok(CompOp::Lt));
    /// assert_eq!(VersionCompare::compare("1", "0.1"), Ok(CompOp::Gt));
    /// ```
    pub fn compare(a: &str, b: &str) -> Result<CompOp, ()> {
        // Create version instances
        let a_ver = Version::from(a);
        let b_ver = Version::from(b);

        // Both version numbers must have been parsed
        if a_ver.is_none() || b_ver.is_none() {
            return Err(());
        }

        // Compare and return the result
        Ok(a_ver.unwrap().compare(&b_ver.unwrap()))
    }

    /// Compare two version number strings to each other and check whether the given comparison
    /// `operator` is valid.
    ///
    /// The two given version numbers must be valid, or an error will be returned.
    ///
    /// # Examples
    ///
    /// ```
    /// use version_compare::VersionCompare;
    /// use version_compare::comp_op::CompOp;
    ///
    /// // Compare version numbers
    /// assert!(VersionCompare::compare_to("1.2.3", "1.2.3", &CompOp::Eq).unwrap());
    /// assert!(VersionCompare::compare_to("1.2.3", "1.2.3", &CompOp::Le).unwrap());
    /// assert!(VersionCompare::compare_to("1.2.3", "1.2.4", &CompOp::Lt).unwrap());
    /// assert!(VersionCompare::compare_to("1", "0.1", &CompOp::Gt).unwrap());
    /// assert!(VersionCompare::compare_to("1", "0.1", &CompOp::Ge).unwrap());
    /// ```
    pub fn compare_to(a: &str, b: &str, operator: &CompOp) -> Result<bool, ()> {
        // Create version instances
        let a_ver = Version::from(a);
        let b_ver = Version::from(b);

        // Both version numbers must have been parsed
        if a_ver.is_none() || b_ver.is_none() {
            return Err(());
        }

        // Compare and return the result
        Ok(a_ver.unwrap().compare_to(&b_ver.unwrap(), &operator))
    }
}

#[cfg(test)]
mod tests {
    use comp_op::CompOp;
    use test::test_version_set::{TEST_VERSION_SETS, TEST_VERSION_SETS_ERROR};
    use super::VersionCompare;

    #[test]
    fn compare() {
        // Compare each version in the version set
        for entry in TEST_VERSION_SETS {
            assert_eq!(
                VersionCompare::compare(&entry.0, &entry.1),
                Ok(entry.2.clone())
            );
        }

        // Compare each error version in the version set
        for entry in TEST_VERSION_SETS_ERROR {
            let result = VersionCompare::compare(&entry.0, &entry.1);

            if result.is_ok() {
                assert!(result != Ok(entry.2.clone()));
            }
        }
    }

    #[test]
    fn compare_to() {
        // Compare each version in the version set
        for entry in TEST_VERSION_SETS {
            // Test
            assert!(VersionCompare::compare_to(&entry.0, &entry.1, &entry.2).unwrap());

            // Make sure the inverse operator is not correct
            assert_eq!(VersionCompare::compare_to(&entry.0, &entry.1, &entry.2.invert()).unwrap(), false);
        }

        // Compare each error version in the version set
        for entry in TEST_VERSION_SETS_ERROR {
            let result = VersionCompare::compare_to(&entry.0, &entry.1, &entry.2);

            if result.is_ok() {
                assert!(!result.unwrap())
            }
        }

        // Assert an exceptional case, compare to not equal
        assert!(VersionCompare::compare_to("1.2.3", "1.2", &CompOp::Ne).unwrap());
    }
}