var_num 0.4.2

Variable length number implementation that can be used as a drop in replacement for any number primitive.
Documentation
use crate::inner::VarInt;
use std::ops::Sub;

impl Sub for VarInt {
    type Output = VarInt;

    fn sub(self, rhs: Self) -> Self::Output {
        let (lhs, rhs) = VarInt::normalize(self, rhs);
        if rhs.is_zero() {
            return lhs;
        }

        if lhs.is_zero() {
            return -rhs;
        }

        match (lhs, rhs) {
            (VarInt::I8(a), VarInt::I8(b)) => match a.checked_sub(b) {
                Some(v) => VarInt::I8(v),
                None => VarInt::I16(a as i16 - b as i16),
            },
            (VarInt::I16(a), VarInt::I16(b)) => match a.checked_sub(b) {
                Some(v) => VarInt::I16(v),
                None => VarInt::I32(a as i32 - b as i32),
            },
            (VarInt::I32(a), VarInt::I32(b)) => match a.checked_sub(b) {
                Some(v) => VarInt::I32(v),
                None => VarInt::I64(a as i64 - b as i64),
            },
            (VarInt::I64(a), VarInt::I64(b)) => match a.checked_sub(b) {
                Some(v) => VarInt::I64(v),
                None => VarInt::I128(a as i128 - b as i128),
            },
            (VarInt::I128(a), VarInt::I128(b)) => match a.checked_sub(b) {
                Some(v) => VarInt::I128(v),
                None => panic!("overflow: {:?} - {:?}", a, b),
            },
            (lhs, rhs) => panic!("normalization failed: {:?} - {:?}", lhs, rhs),
        }
    }
}