use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign};
#[derive(Clone, Debug)]
pub struct Version {
vector: Vec<u64>
}
impl Version {
pub fn new(vector: Vec<u64>) -> Self {
Self { vector }
}
pub fn from_split_callback<F>(input: &str, callback: F) -> Self
where F: Fn(char) -> bool {
Self {
vector: input.split(|c: char| callback(c))
.map(|c| c.parse::<u64>().unwrap())
.collect(),
}
}
pub fn from_str(input: &str) -> Self {
Self {
vector: input.split(|c: char| !c.is_numeric())
.map(|c| c.parse::<u64>().unwrap())
.collect(),
}
}
pub fn from_vec(vector: Vec<u64>) -> Self {
Self { vector }
}
pub fn to_vector(self) -> Vec<u64> {
self.vector
}
}
impl PartialEq for Version {
fn eq(&self, other: &Self) -> bool {
self.vector == other.vector
}
}
impl Eq for Version {}
impl Ord for Version {
fn cmp(&self, other: &Self) -> Ordering {
self.vector.iter().cmp(other.vector.iter())
}
}
impl PartialOrd for Version {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Add for Version {
type Output = Self;
fn add(self, other: Self) -> Self {
let mut vector: Vec<u64> = vec![];
let mut other_iter = other.vector.iter();
let mut self_iter = self.vector.iter();
loop {
let self_next = self_iter.next();
let other_next = other_iter.next();
match (self_next, other_next) {
(Some(self_value), Some(other_value)) => {
vector.push(self_value + other_value);
},
(Some(self_value), _) => {
vector.push(self_value + 0);
},
(_, Some(other_value)) => {
vector.push(0 + other_value);
},
(_, _) => {
break;
},
};
}
Self { vector }
}
}
impl AddAssign for Version {
fn add_assign(&mut self, other: Self) {
let mut vector: Vec<u64> = vec![];
let mut other_iter = other.vector.iter();
let mut self_iter = self.vector.iter();
loop {
let self_next = self_iter.next();
let other_next = other_iter.next();
match (self_next, other_next) {
(Some(self_value), Some(other_value)) => {
vector.push(self_value + other_value);
},
(Some(self_value), _) => {
vector.push(self_value + 0);
},
(_, Some(other_value)) => {
vector.push(0 + other_value);
},
(_, _) => {
break;
},
};
}
*self = Self { vector };
}
}
impl Sub for Version {
type Output = Self;
fn sub(self, other: Self) -> Self {
let mut vector: Vec<u64> = vec![];
let mut other_iter = other.vector.iter();
let mut self_iter = self.vector.iter();
loop {
let self_next = self_iter.next();
let other_next = other_iter.next();
match (self_next, other_next) {
(Some(self_value), Some(other_value)) => {
vector.push(self_value - other_value);
},
(Some(self_value), _) => {
vector.push(self_value - 0);
},
(_, Some(other_value)) => {
vector.push(0 - other_value);
},
(_, _) => {
break;
},
};
}
Self { vector }
}
}
impl SubAssign for Version {
fn sub_assign(&mut self, other: Self) {
let mut vector: Vec<u64> = vec![];
let mut other_iter = other.vector.iter();
let mut self_iter = self.vector.iter();
loop {
let self_next = self_iter.next();
let other_next = other_iter.next();
match (self_next, other_next) {
(Some(self_value), Some(other_value)) => {
vector.push(self_value - other_value);
},
(Some(self_value), _) => {
vector.push(self_value - 0);
},
(_, Some(other_value)) => {
vector.push(0 - other_value);
},
(_, _) => {
break;
},
};
}
*self = Self { vector };
}
}