Skip to main content

clack_common/utils/
version.rs

1use clap_sys::version::clap_version;
2use std::cmp::Ordering;
3use std::fmt::{Display, Formatter};
4
5/// A CLAP version identifier.
6#[derive(Debug, Copy, Clone, Eq, PartialEq)]
7pub struct ClapVersion {
8    /// The major version number.
9    ///
10    /// A change in this number indicates an incompatible ABI or API change.
11    ///
12    /// Version `0.x.y` is the development stage, and ABI or API stability is not guaranteed.
13    pub major: u32,
14
15    /// The minor version number.
16    ///
17    /// A change in this number indicates a compatible API extension.
18    pub minor: u32,
19
20    /// The revision version number.
21    ///
22    /// A change in this number indicates a bug fix or other compatible change.
23    pub revision: u32,
24}
25
26impl ClapVersion {
27    /// The version of the CLAP API that is implemented by this Clack implementation.
28    pub const CURRENT: ClapVersion = Self::from_raw(clap_sys::version::CLAP_VERSION);
29
30    /// Creates a [`ClapVersion`] from its raw, C-FFI compatible representation.
31    #[inline]
32    pub const fn from_raw(raw: clap_version) -> Self {
33        Self {
34            major: raw.major,
35            minor: raw.minor,
36            revision: raw.revision,
37        }
38    }
39
40    /// Returns this [`ClapVersion`] as its raw, C-FFI compatible representation.
41    #[inline]
42    pub const fn to_raw(self) -> clap_version {
43        clap_version {
44            major: self.major,
45            minor: self.minor,
46            revision: self.revision,
47        }
48    }
49
50    /// Returns whether this [`ClapVersion`] is compatible with the current version of this `clack`
51    /// library.
52    ///
53    /// This currently returns true if this version's `major` field is `1`, and false
54    /// otherwise.
55    #[inline]
56    pub const fn is_compatible(&self) -> bool {
57        clap_sys::version::clap_version_is_compatible(self.to_raw())
58    }
59}
60
61impl PartialOrd for ClapVersion {
62    #[inline]
63    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
64        Some(self.cmp(other))
65    }
66}
67
68impl Ord for ClapVersion {
69    fn cmp(&self, other: &Self) -> Ordering {
70        match self.major.cmp(&other.major) {
71            Ordering::Equal => match self.minor.cmp(&other.minor) {
72                Ordering::Equal => self.revision.cmp(&other.revision),
73                o => o,
74            },
75            o => o,
76        }
77    }
78}
79
80impl Display for ClapVersion {
81    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
82        write!(f, "{}.{}.{}", self.major, self.minor, self.revision)
83    }
84}
85
86#[cfg(test)]
87mod test {
88    use super::*;
89
90    #[test]
91    pub fn display() {
92        let version = ClapVersion {
93            major: 1,
94            minor: 5,
95            revision: 3,
96        };
97        let display = format!("{version}");
98
99        assert_eq!(&"1.5.3", &display);
100    }
101
102    #[test]
103    pub fn version_ordering() {
104        let version = ClapVersion {
105            major: 1,
106            minor: 5,
107            revision: 3,
108        };
109
110        assert_eq!(
111            version,
112            ClapVersion {
113                major: 1,
114                minor: 5,
115                revision: 3,
116            }
117        );
118
119        assert!(
120            version
121                > ClapVersion {
122                    major: 1,
123                    minor: 4,
124                    revision: 3
125                }
126        );
127
128        assert!(
129            version
130                < ClapVersion {
131                    major: 2,
132                    minor: 1,
133                    revision: 1
134                }
135        );
136
137        assert!(
138            version
139                < ClapVersion {
140                    major: 1,
141                    minor: 5,
142                    revision: 5
143                }
144        );
145
146        assert_eq!(
147            Ordering::Equal,
148            version.cmp(&ClapVersion {
149                major: 1,
150                minor: 5,
151                revision: 3
152            })
153        );
154    }
155}