version_operators 0.0.1

Rust library for comparing and manipulating version numbers
Documentation

use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign};


#[derive(Clone, Debug)]
pub struct Version {
    vector: Vec<u64>
}

impl Version {
    /// Create new instance from vector
    ///
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let vector = vec![1, 14, 3];
    ///
    /// let version = Version::new(vector.clone());
    ///
    /// assert_eq!(version.to_vector(), vector);
    /// ```
    pub fn new(vector: Vec<u64>) -> Self {
        Self { vector }
    }

    /// Create new instance using a custom spliter callback function or closure
    ///
    /// ## Example with Closure
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version = Version::from_split_callback("1.14.3", |c: char| !c.is_numeric());
    ///
    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
    /// ```
    ///
    /// ## Example with Function
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// fn custom_spliter(c: char) -> bool {
    ///     !c.is_numeric()
    /// }
    ///
    /// let version = Version::from_split_callback("1.14.3", &custom_spliter);
    ///
    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
    /// ```
    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(),
        }
    }

    /// Convert `&str` to vector of unsigned-integers
    ///
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version = Version::from_str("1.14.3");
    ///
    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
    /// ```
    pub fn from_str(input: &str) -> Self {
        Self {
            vector: input.split(|c: char| !c.is_numeric())
                         .map(|c| c.parse::<u64>().unwrap())
                         .collect(),
        }
    }

    /// Save vector of unsigned-integers to new instance of Version
    ///
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let vector = vec![1, 14, 3];
    /// let version = Version::from_vec(vector.clone());
    ///
    /// assert_eq!(version.to_vector(), vector);
    /// ```
    pub fn from_vec(vector: Vec<u64>) -> Self {
        Self { vector }
    }

    /// Passes ownership of vector within Version instance
    ///
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version = Version::from_str("1.14.3");
    ///
    /// assert_eq!(version.to_vector(), vec![1, 14, 3]);
    /// ```
    pub fn to_vector(self) -> Vec<u64> {
        self.vector
    }
}


/// Implement equal/not-equal (`==`, `!=`) operators
impl PartialEq for Version {
    /// ## Example Equality
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14.3");
    ///
    /// assert!(version_one == version_two);
    /// assert_eq!(version_one, version_two);
    /// ```
    ///
    /// ## Example Inequality
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version_one = Version::from_str("1.14");
    /// let version_two = Version::from_str("1.14.2");
    ///
    /// assert!(version_one != version_two);
    /// assert_ne!(version_one, version_two);
    /// ```
    fn eq(&self, other: &Self) -> bool {
        self.vector == other.vector
    }
}

/// See: `PartialEq` implementation
impl Eq for Version {}


/// Implement greater/less-than (`<`, `>`) and operators
impl Ord for Version {
    /// ## Example Greater Than
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14.2");
    ///
    /// assert!(version_one > version_two);
    /// assert_eq!(version_two > version_one, false);
    /// ```
    ///
    /// ## Example Less Than
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14");
    ///
    /// assert!(version_two < version_one);
    /// assert_eq!(version_one < version_two, false);
    /// ```
    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))
    }
}


/// Implement addition (`+`) operator
impl Add for Version {
    type Output = Self;

    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14.2");
    ///
    /// let version_new = version_one + version_two;
    ///
    /// assert!(version_new.to_vector() == vec![2, 28, 5]);
    /// ```
    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 }
    }
}


/// Implement add assignment (`+=`) operator
impl AddAssign for Version {
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let mut version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14.2");
    ///
    /// version_one += version_two;
    ///
    /// assert!(version_one.to_vector() == vec![2, 28, 5]);
    /// ```
    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 };
    }
}


/// Implement subtraction (`-`) operator
impl Sub for Version {
    type Output = Self;

    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    /// 
    /// let version_one = Version::from_str("1.14.3");
    /// let version_two = Version::from_str("1.14.2");
    ///
    /// let version_new = version_one - version_two;
    ///
    /// assert!(version_new.to_vector() == vec![0, 0, 1]);
    /// ```
    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 }
    }
}


/// Implement subtract assignment (`-=`) operator
impl SubAssign for Version {
    /// ## Example
    ///
    /// ```rust
    /// use version_operators::Version;
    ///
    /// let mut version = Version::from_str("1.14.3");
    ///
    /// version -= Version::from_str("1.14.2");
    ///
    /// assert!(version.to_vector() == vec![0, 0, 1]);
    /// ```
    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 };
    }
}