[pbs-devel] [PATCH v2 proxmox-backup 2/3] api types: version: implement traits to allow for version comparison
Christian Ebner
c.ebner at proxmox.com
Thu Nov 28 17:07:20 CET 2024
Derive and implement the traits to allow comparison of two
`ApiVersion` instances for more direct and easy api version
comparisons. Further, add some basic test cases to reduce risk of
regressions.
This is useful for e.g. feature compatibility checks by comparing api
versions of remote instances.
Example comparison:
```
api_version >= ApiVersion::new(3, 3, 0)
```
Signed-off-by: Christian Ebner <c.ebner at proxmox.com>
---
changes since version 1:
- implement traits for operator based version comparison
- add basic regression tests
pbs-api-types/src/version.rs | 122 +++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/pbs-api-types/src/version.rs b/pbs-api-types/src/version.rs
index bd4c517da..09e725eb6 100644
--- a/pbs-api-types/src/version.rs
+++ b/pbs-api-types/src/version.rs
@@ -1,4 +1,5 @@
//! Defines the types for the api version info endpoint
+use std::cmp::Ordering;
use std::convert::TryFrom;
use anyhow::{format_err, Context};
@@ -33,6 +34,7 @@ pub type ApiVersionMajor = u64;
pub type ApiVersionMinor = u64;
pub type ApiVersionRelease = u64;
+#[derive(PartialEq, Eq)]
pub struct ApiVersion {
pub major: ApiVersionMajor,
pub minor: ApiVersionMinor,
@@ -66,3 +68,123 @@ impl TryFrom<ApiVersionInfo> for ApiVersion {
})
}
}
+
+impl PartialOrd for ApiVersion {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let ordering = match (
+ self.major.cmp(&other.major),
+ self.minor.cmp(&other.minor),
+ self.release.cmp(&other.release),
+ ) {
+ (Ordering::Equal, Ordering::Equal, ordering) => ordering,
+ (Ordering::Equal, ordering, _) => ordering,
+ (ordering, _, _) => ordering,
+ };
+
+ Some(ordering)
+ }
+}
+
+impl ApiVersion {
+ pub fn new(major: ApiVersionMajor, minor: ApiVersionMinor, release: ApiVersionRelease) -> Self {
+ Self {
+ major,
+ minor,
+ release,
+ }
+ }
+}
+
+#[test]
+fn same_level_version_comarison() {
+ let major_base = ApiVersion::new(2, 0, 0);
+ let major_less = ApiVersion::new(1, 0, 0);
+ let major_greater = ApiVersion::new(3, 0, 0);
+
+ let minor_base = ApiVersion::new(2, 2, 0);
+ let minor_less = ApiVersion::new(2, 1, 0);
+ let minor_greater = ApiVersion::new(2, 3, 0);
+
+ let release_base = ApiVersion::new(2, 2, 2);
+ let release_less = ApiVersion::new(2, 2, 1);
+ let release_greater = ApiVersion::new(2, 2, 3);
+
+ assert!(major_base == major_base);
+ assert!(minor_base == minor_base);
+ assert!(release_base == release_base);
+
+ assert!(major_base > major_less);
+ assert!(major_base >= major_less);
+ assert!(major_base != major_less);
+
+ assert!(major_base < major_greater);
+ assert!(major_base <= major_greater);
+ assert!(major_base != major_greater);
+
+ assert!(minor_base > minor_less);
+ assert!(minor_base >= minor_less);
+ assert!(minor_base != minor_less);
+
+ assert!(minor_base < minor_greater);
+ assert!(minor_base <= minor_greater);
+ assert!(minor_base != minor_greater);
+
+ assert!(release_base > release_less);
+ assert!(release_base >= release_less);
+ assert!(release_base != release_less);
+
+ assert!(release_base < release_greater);
+ assert!(release_base <= release_greater);
+ assert!(release_base != release_greater);
+}
+
+#[test]
+fn mixed_level_version_comarison() {
+ let major_base = ApiVersion::new(2, 0, 0);
+ let major_less = ApiVersion::new(1, 0, 0);
+ let major_greater = ApiVersion::new(3, 0, 0);
+
+ let minor_base = ApiVersion::new(2, 2, 0);
+ let minor_less = ApiVersion::new(2, 1, 0);
+ let minor_greater = ApiVersion::new(2, 3, 0);
+
+ let release_base = ApiVersion::new(2, 2, 2);
+ let release_less = ApiVersion::new(2, 2, 1);
+ let release_greater = ApiVersion::new(2, 2, 3);
+
+ assert!(major_base < minor_base);
+ assert!(major_base < minor_less);
+ assert!(major_base < minor_greater);
+
+ assert!(major_base < release_base);
+ assert!(major_base < release_less);
+ assert!(major_base < release_greater);
+
+ assert!(major_less < minor_base);
+ assert!(major_less < minor_less);
+ assert!(major_less < minor_greater);
+
+ assert!(major_less < release_base);
+ assert!(major_less < release_less);
+ assert!(major_less < release_greater);
+
+ assert!(major_greater > minor_base);
+ assert!(major_greater > minor_less);
+ assert!(major_greater > minor_greater);
+
+ assert!(major_greater > release_base);
+ assert!(major_greater > release_less);
+ assert!(major_greater > release_greater);
+
+ assert!(minor_base < release_base);
+ assert!(minor_base < release_less);
+ assert!(minor_base < release_greater);
+
+ assert!(minor_greater > release_base);
+ assert!(minor_greater > release_less);
+ assert!(minor_greater > release_greater);
+
+ assert!(minor_less < release_base);
+ assert!(minor_less < release_less);
+ assert!(minor_less < release_greater);
+}
--
2.39.5
More information about the pbs-devel
mailing list