astarte_interfaces/interface/
version.rs1use std::fmt::Display;
24
25#[derive(Debug, thiserror::Error)]
27pub enum VersionError {
28 #[error("the version cannot be negative: {major}.{minor}")]
30 Negative {
31 major: i32,
33 minor: i32,
35 },
36 #[error("the version of an interface cannot be 0.0")]
38 Zero,
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub struct InterfaceVersion {
50 version_major: i32,
51 version_minor: i32,
52}
53
54impl InterfaceVersion {
55 pub fn try_new(version_major: i32, version_minor: i32) -> Result<Self, VersionError> {
57 if version_major.is_negative() || version_minor.is_negative() {
58 return Err(VersionError::Negative {
59 major: version_major,
60 minor: version_minor,
61 });
62 }
63
64 if version_major == 0 && version_minor == 0 {
65 return Err(VersionError::Zero);
66 }
67
68 Ok(Self {
70 version_major,
71 version_minor,
72 })
73 }
74
75 #[must_use]
77 pub fn version_major(&self) -> i32 {
78 self.version_major
79 }
80
81 #[must_use]
83 pub fn version_minor(&self) -> i32 {
84 self.version_minor
85 }
86}
87
88impl Display for InterfaceVersion {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 write!(f, "{}.{}", self.version_major, self.version_minor)
91 }
92}
93
94impl From<&InterfaceVersion> for (i32, i32) {
95 fn from(value: &InterfaceVersion) -> Self {
96 (value.version_major, value.version_minor)
97 }
98}
99
100impl From<InterfaceVersion> for (i32, i32) {
101 fn from(value: InterfaceVersion) -> Self {
102 (value.version_major, value.version_minor)
103 }
104}
105
106impl TryFrom<(i32, i32)> for InterfaceVersion {
107 type Error = VersionError;
108
109 fn try_from((major, minor): (i32, i32)) -> Result<Self, Self::Error> {
110 Self::try_new(major, minor)
111 }
112}
113
114impl Default for InterfaceVersion {
115 fn default() -> Self {
116 Self {
117 version_major: 0,
118 version_minor: 1,
119 }
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use pretty_assertions::assert_eq;
126
127 use super::*;
128
129 #[test]
130 fn check_into() {
131 let ver = InterfaceVersion::try_from((0, 1)).unwrap();
132 let ver: (i32, i32) = ver.into();
133
134 assert_eq!(ver, (0, 1));
135 }
136
137 #[test]
138 fn check_negative() {
139 InterfaceVersion::try_from((0, -1)).unwrap_err();
140 InterfaceVersion::try_from((-1, 0)).unwrap_err();
141 InterfaceVersion::try_from((-1, -1)).unwrap_err();
142 }
143
144 #[test]
145 fn check_zero() {
146 InterfaceVersion::try_from((0, 0)).unwrap_err();
147 }
148
149 #[test]
150 fn check_default() {
151 assert_eq!(
152 InterfaceVersion::default(),
153 InterfaceVersion {
154 version_major: 0,
155 version_minor: 1
156 }
157 );
158 }
159
160 #[test]
161 fn check_getters() {
162 let ver = InterfaceVersion::default();
163
164 assert_eq!(ver.version_major(), 0);
165 assert_eq!(ver.version_minor(), 1);
166 }
167
168 #[test]
169 fn check_display() {
170 let ver = InterfaceVersion::try_from((0, 1)).unwrap().to_string();
171 assert_eq!(ver, "0.1");
172 }
173}