algorithmify 0.1.1

Create specifications for algorithms defined using Rust code
Documentation
use std::ops::{Add, BitAnd, BitOr, Div, Mul, Sub};

#[derive(Debug, Copy, Clone)]
pub enum Integer {
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    Isize(isize),
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    Usize(usize),
}

impl Integer {
    pub fn as_i64(&self) -> i64 {
        match self {
            Self::I8(value) => *value as i64,
            Self::I16(value) => *value as i64,
            Self::I32(value) => *value as i64,
            Self::I64(value) => *value,
            Self::Isize(value) => *value as i64,
            Self::U8(value) => *value as i64,
            Self::U16(value) => *value as i64,
            Self::U32(value) => *value as i64,
            Self::U64(value) => *value as i64,
            Self::Usize(value) => *value as i64,
        }
    }

    pub fn as_usize(&self) -> usize {
        match self {
            Self::I8(value) => *value as usize,
            Self::I16(value) => *value as usize,
            Self::I32(value) => *value as usize,
            Self::I64(value) => *value as usize,
            Self::Isize(value) => *value as usize,
            Self::U8(value) => *value as usize,
            Self::U16(value) => *value as usize,
            Self::U32(value) => *value as usize,
            Self::U64(value) => *value as usize,
            Self::Usize(value) => *value,
        }
    }
}

impl Add for Integer {
    type Output = Self;

    fn add(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs + rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs + rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs + rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs + rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs + rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs + rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs + rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs + rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs + rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs + rhs),
            _ => Self::I64(self.as_i64() + rhs.as_i64()),
        }
    }
}

impl Sub for Integer {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs - rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs - rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs - rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs - rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs - rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs - rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs - rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs - rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs - rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs - rhs),
            _ => Self::I64(self.as_i64() - rhs.as_i64()),
        }
    }
}

impl Mul for Integer {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs * rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs * rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs * rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs * rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs * rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs * rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs * rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs * rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs * rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs * rhs),
            _ => Self::I64(self.as_i64() * rhs.as_i64()),
        }
    }
}

impl Div for Integer {
    type Output = Self;

    fn div(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs / rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs / rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs / rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs / rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs / rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs / rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs / rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs / rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs / rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs / rhs),
            _ => Self::I64(self.as_i64() / rhs.as_i64()),
        }
    }
}

impl BitAnd for Integer {
    type Output = Self;

    fn bitand(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs & rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs & rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs & rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs & rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs & rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs & rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs & rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs & rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs & rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs & rhs),
            _ => Self::I64(self.as_i64() & rhs.as_i64()),
        }
    }
}

impl BitOr for Integer {
    type Output = Self;

    fn bitor(self, rhs: Self) -> Self::Output {
        match (self, rhs) {
            (Self::I8(lhs), Self::I8(rhs)) => Self::I8(lhs | rhs),
            (Self::I16(lhs), Self::I16(rhs)) => Self::I16(lhs | rhs),
            (Self::I32(lhs), Self::I32(rhs)) => Self::I32(lhs | rhs),
            (Self::I64(lhs), Self::I64(rhs)) => Self::I64(lhs | rhs),
            (Self::Isize(lhs), Self::Isize(rhs)) => Self::Isize(lhs | rhs),
            (Self::U8(lhs), Self::U8(rhs)) => Self::U8(lhs | rhs),
            (Self::U16(lhs), Self::U16(rhs)) => Self::U16(lhs | rhs),
            (Self::U32(lhs), Self::U32(rhs)) => Self::U32(lhs | rhs),
            (Self::U64(lhs), Self::U64(rhs)) => Self::U64(lhs | rhs),
            (Self::Usize(lhs), Self::Usize(rhs)) => Self::Usize(lhs | rhs),
            _ => Self::I64(self.as_i64() | rhs.as_i64()),
        }
    }
}

impl PartialEq for Integer {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::I8(l0), Self::I8(r0)) => l0 == r0,
            (Self::I16(l0), Self::I16(r0)) => l0 == r0,
            (Self::I32(l0), Self::I32(r0)) => l0 == r0,
            (Self::I64(l0), Self::I64(r0)) => l0 == r0,
            (Self::Isize(l0), Self::Isize(r0)) => l0 == r0,
            (Self::U8(l0), Self::U8(r0)) => l0 == r0,
            (Self::U16(l0), Self::U16(r0)) => l0 == r0,
            (Self::U32(l0), Self::U32(r0)) => l0 == r0,
            (Self::U64(l0), Self::U64(r0)) => l0 == r0,
            (Self::Usize(l0), Self::Usize(r0)) => l0 == r0,
            _ => self.as_i64() == other.as_i64(),
        }
    }
}

impl PartialOrd for Integer {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.as_i64().partial_cmp(&other.as_i64())
    }
}