Skip to main content

avalanche_types/utils/
version.rs

1use std::{
2    clone::Clone,
3    cmp::Ordering,
4    hash::{Hash, Hasher},
5};
6
7#[derive(Clone, Debug, Eq)]
8pub struct ApplicationVersion {
9    pub app: String,
10    pub major: u32,
11    pub minor: u32,
12    pub patch: u32,
13}
14
15impl Ord for ApplicationVersion {
16    fn cmp(&self, other: &ApplicationVersion) -> Ordering {
17        self.major
18            .cmp(&other.major) // returns when major versions are not equal
19            .then_with(
20                || self.minor.cmp(&other.minor), // if major versions are Equal, compare the minor
21            )
22            .then_with(
23                || self.patch.cmp(&other.patch), // if major/minor versions are Equal, compare the patch
24            )
25    }
26}
27
28impl PartialOrd for ApplicationVersion {
29    fn partial_cmp(&self, other: &ApplicationVersion) -> Option<Ordering> {
30        Some(self.cmp(other))
31    }
32}
33
34impl PartialEq for ApplicationVersion {
35    fn eq(&self, other: &ApplicationVersion) -> bool {
36        self.cmp(other) == Ordering::Equal
37    }
38}
39
40/// ref. <https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq>
41impl Hash for ApplicationVersion {
42    fn hash<H: Hasher>(&self, state: &mut H) {
43        self.app.hash(state);
44        self.major.hash(state);
45        self.minor.hash(state);
46        self.patch.hash(state);
47    }
48}
49
50impl ApplicationVersion {
51    pub fn before(&self, other: &ApplicationVersion) -> bool {
52        if self.app != other.app {
53            return false;
54        }
55        self.cmp(other) == Ordering::Less
56    }
57}
58
59/// RUST_LOG=debug cargo test --package avalanche-types --lib -- utils::version::test_version --exact --show-output
60#[test]
61fn test_version() {
62    // lengths of individual ids do not matter since all are fixed-sized
63    let v1 = ApplicationVersion {
64        app: String::from("hello"),
65        major: 1,
66        minor: 7,
67        patch: 15,
68    };
69    let v2 = ApplicationVersion {
70        app: String::from("hello"),
71        major: 1,
72        minor: 7,
73        patch: 15,
74    };
75    let v3 = ApplicationVersion {
76        app: String::from("hello"),
77        major: 1,
78        minor: 7,
79        patch: 17,
80    };
81    let v4 = ApplicationVersion {
82        app: String::from("hello2"),
83        major: 1,
84        minor: 7,
85        patch: 17,
86    };
87    assert!(v1 == v2);
88    assert!(v1 < v3 && v2 < v3);
89    assert!(v1.before(&v3) && v2.before(&v3));
90    assert!(!v1.before(&v4) && !v2.before(&v4) && !v3.before(&v4));
91}