version_operators/
lib.rs

1
2use std::cmp::Ordering;
3use std::ops::{Add, AddAssign, Sub, SubAssign};
4
5
6#[derive(Clone, Debug)]
7pub struct Version {
8    vector: Vec<u64>
9}
10
11impl Version {
12    /// Create new instance from vector
13    ///
14    /// ## Example
15    ///
16    /// ```rust
17    /// use version_operators::Version;
18    ///
19    /// let vector = vec![1, 14, 3];
20    ///
21    /// let version = Version::new(vector.clone());
22    ///
23    /// assert_eq!(version.to_vector(), vector);
24    /// ```
25    pub fn new(vector: Vec<u64>) -> Self {
26        Self { vector }
27    }
28
29    /// Create new instance using a custom spliter callback function or closure
30    ///
31    /// ## Example with Closure
32    ///
33    /// ```rust
34    /// use version_operators::Version;
35    ///
36    /// let version = Version::from_split_callback("1.14.3", |c: char| !c.is_numeric());
37    ///
38    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
39    /// ```
40    ///
41    /// ## Example with Function
42    ///
43    /// ```rust
44    /// use version_operators::Version;
45    ///
46    /// fn custom_spliter(c: char) -> bool {
47    ///     !c.is_numeric()
48    /// }
49    ///
50    /// let version = Version::from_split_callback("1.14.3", &custom_spliter);
51    ///
52    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
53    /// ```
54    pub fn from_split_callback<F>(input: &str, callback: F) -> Self
55            where F: Fn(char) -> bool {
56        Self {
57            vector: input.split(|c: char| callback(c))
58                         .map(|c| c.parse::<u64>().unwrap())
59                         .collect(),
60        }
61    }
62
63    /// Convert `&str` to vector of unsigned-integers
64    ///
65    /// ## Example
66    ///
67    /// ```rust
68    /// use version_operators::Version;
69    ///
70    /// let version = Version::from_str("1.14.3");
71    ///
72    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
73    /// ```
74    pub fn from_str(input: &str) -> Self {
75        Self {
76            vector: input.split(|c: char| !c.is_numeric())
77                         .map(|c| c.parse::<u64>().unwrap())
78                         .collect(),
79        }
80    }
81
82    /// Save vector of unsigned-integers to new instance of Version
83    ///
84    /// ## Example
85    ///
86    /// ```rust
87    /// use version_operators::Version;
88    ///
89    /// let vector = vec![1, 14, 3];
90    /// let version = Version::from_vec(vector.clone());
91    ///
92    /// assert_eq!(version.to_vector(), vector);
93    /// ```
94    pub fn from_vec(vector: Vec<u64>) -> Self {
95        Self { vector }
96    }
97
98    /// Passes ownership of vector within Version instance
99    ///
100    /// ## Example
101    ///
102    /// ```rust
103    /// use version_operators::Version;
104    ///
105    /// let version = Version::from_str("1.14.3");
106    ///
107    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
108    /// ```
109    pub fn to_vector(self) -> Vec<u64> {
110        self.vector
111    }
112}
113
114
115/// Implement equal/not-equal (`==`, `!=`) operators
116impl PartialEq for Version {
117    /// ## Example Equality
118    ///
119    /// ```rust
120    /// use version_operators::Version;
121    ///
122    /// let version_one = Version::from_str("1.14.3");
123    /// let version_two = Version::from_str("1.14.3");
124    ///
125    /// assert!(version_one == version_two);
126    /// assert_eq!(version_one, version_two);
127    /// ```
128    ///
129    /// ## Example Inequality
130    ///
131    /// ```rust
132    /// use version_operators::Version;
133    ///
134    /// let version_one = Version::from_str("1.14");
135    /// let version_two = Version::from_str("1.14.2");
136    ///
137    /// assert!(version_one != version_two);
138    /// assert_ne!(version_one, version_two);
139    /// ```
140    fn eq(&self, other: &Self) -> bool {
141        self.vector == other.vector
142    }
143}
144
145/// See: `PartialEq` implementation
146impl Eq for Version {}
147
148
149/// Implement greater/less-than (`<`, `>`) and operators
150impl Ord for Version {
151    /// ## Example Greater Than
152    ///
153    /// ```rust
154    /// use version_operators::Version;
155    ///
156    /// let version_one = Version::from_str("1.14.3");
157    /// let version_two = Version::from_str("1.14.2");
158    ///
159    /// assert!(version_one > version_two);
160    /// assert_eq!(version_two > version_one, false);
161    /// ```
162    ///
163    /// ## Example Less Than
164    ///
165    /// ```rust
166    /// use version_operators::Version;
167    ///
168    /// let version_one = Version::from_str("1.14.3");
169    /// let version_two = Version::from_str("1.14");
170    ///
171    /// assert!(version_two < version_one);
172    /// assert_eq!(version_one < version_two, false);
173    /// ```
174    fn cmp(&self, other: &Self) -> Ordering {
175        self.vector.iter().cmp(other.vector.iter())
176    }
177}
178
179
180impl PartialOrd for Version {
181    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
182        Some(self.cmp(other))
183    }
184}
185
186
187/// Implement addition (`+`) operator
188impl Add for Version {
189    type Output = Self;
190
191    /// ## Example
192    ///
193    /// ```rust
194    /// use version_operators::Version;
195    ///
196    /// let version_one = Version::from_str("1.14.3");
197    /// let version_two = Version::from_str("1.14.2");
198    ///
199    /// let version_new = version_one + version_two;
200    ///
201    /// assert!(version_new.to_vector() == vec![2, 28, 5]);
202    /// ```
203    fn add(self, other: Self) -> Self {
204        let mut vector: Vec<u64> = vec![];
205        let mut other_iter = other.vector.iter();
206        let mut self_iter = self.vector.iter();
207        loop {
208            let self_next = self_iter.next();
209            let other_next = other_iter.next();
210            match (self_next, other_next) {
211                (Some(self_value), Some(other_value)) => {
212                    vector.push(self_value + other_value);
213                },
214                (Some(self_value), _) => {
215                    vector.push(self_value + 0);
216                },
217                (_, Some(other_value)) => {
218                    vector.push(0 + other_value);
219                },
220                (_, _) => {
221                    break;
222                },
223            };
224        }
225        Self { vector }
226    }
227}
228
229
230/// Implement add assignment (`+=`) operator
231impl AddAssign for Version {
232    /// ## Example
233    ///
234    /// ```rust
235    /// use version_operators::Version;
236    ///
237    /// let mut version_one = Version::from_str("1.14.3");
238    /// let version_two = Version::from_str("1.14.2");
239    ///
240    /// version_one += version_two;
241    ///
242    /// assert!(version_one.to_vector() == vec![2, 28, 5]);
243    /// ```
244    fn add_assign(&mut self, other: Self) {
245        let mut vector: Vec<u64> = vec![];
246        let mut other_iter = other.vector.iter();
247        let mut self_iter = self.vector.iter();
248        loop {
249            let self_next = self_iter.next();
250            let other_next = other_iter.next();
251            match (self_next, other_next) {
252                (Some(self_value), Some(other_value)) => {
253                    vector.push(self_value + other_value);
254                },
255                (Some(self_value), _) => {
256                    vector.push(self_value + 0);
257                },
258                (_, Some(other_value)) => {
259                    vector.push(0 + other_value);
260                },
261                (_, _) => {
262                    break;
263                },
264            };
265        }
266        *self = Self { vector };
267    }
268}
269
270
271/// Implement subtraction (`-`) operator
272impl Sub for Version {
273    type Output = Self;
274
275    /// ## Example
276    ///
277    /// ```rust
278    /// use version_operators::Version;
279    /// 
280    /// let version_one = Version::from_str("1.14.3");
281    /// let version_two = Version::from_str("1.14.2");
282    ///
283    /// let version_new = version_one - version_two;
284    ///
285    /// assert!(version_new.to_vector() == vec![0, 0, 1]);
286    /// ```
287    fn sub(self, other: Self) -> Self {
288        let mut vector: Vec<u64> = vec![];
289        let mut other_iter = other.vector.iter();
290        let mut self_iter = self.vector.iter();
291        loop {
292            let self_next = self_iter.next();
293            let other_next = other_iter.next();
294            match (self_next, other_next) {
295                (Some(self_value), Some(other_value)) => {
296                    vector.push(self_value - other_value);
297                },
298                (Some(self_value), _) => {
299                    vector.push(self_value - 0);
300                },
301                (_, Some(other_value)) => {
302                    vector.push(0 - other_value);
303                },
304                (_, _) => {
305                    break;
306                },
307            };
308        }
309        Self { vector }
310    }
311}
312
313
314/// Implement subtract assignment (`-=`) operator
315impl SubAssign for Version {
316    /// ## Example
317    ///
318    /// ```rust
319    /// use version_operators::Version;
320    ///
321    /// let mut version = Version::from_str("1.14.3");
322    ///
323    /// version -= Version::from_str("1.14.2");
324    ///
325    /// assert!(version.to_vector() == vec![0, 0, 1]);
326    /// ```
327    fn sub_assign(&mut self, other: Self) {
328        let mut vector: Vec<u64> = vec![];
329        let mut other_iter = other.vector.iter();
330        let mut self_iter = self.vector.iter();
331        loop {
332            let self_next = self_iter.next();
333            let other_next = other_iter.next();
334            match (self_next, other_next) {
335                (Some(self_value), Some(other_value)) => {
336                    vector.push(self_value - other_value);
337                },
338                (Some(self_value), _) => {
339                    vector.push(self_value - 0);
340                },
341                (_, Some(other_value)) => {
342                    vector.push(0 - other_value);
343                },
344                (_, _) => {
345                    break;
346                },
347            };
348        }
349        *self = Self { vector };
350    }
351}
352