How to use generic types for 'checked_add'?


#1

I want to write a func which can perform safer calculation:

pub fn safe_calc<T>(a: T, b: T, op: operator) -> Result<T, ErrorCases> {
    match op {
        Add => match a.checked_add(b) {
            Some(s) => s,
            None => Err(I32Overflow),
        },
        Sub => .......................
        .............................
    }
}

But, I don’t know what trait should I write for the T.
Or how to write this?

Thank you.


#2

i don’t see any trait for checked add in the std lib so you can either search for a external crate with has the functionality or you write you own trait for it.

e.g.

#[derive(Debug)]
pub struct OverflowError;

pub trait CheckedAdd: Sized {
    fn checked_add(self, rhs: Self) -> Result<Self, OverflowError>;
}

impl CheckedAdd for i8 {
    fn checked_add(self, rhs: i8) -> Result<i8, OverflowError> {
        i8::checked_add(self, rhs).ok_or(OverflowError)
    }
}

pub fn safe_calc<T: CheckedAdd>(a: T, b: T, op: Operator) -> Result<T, OverflowError> {
    match op {
        Operator::Add => CheckedAdd::checked_add(a, b),
        Operator::Sub => unimplemented!(),
    }
}

fn main() {
    let res_i8 = safe_calc(0_i8, 42_i8, Operator::Add);
    println!("0_i8 + 42_i8 = {:?}", res_i8);
}

playground includes a macro to generate the impl’s


#3

The goto crate for generic programming over numeric types is num, they have a CheckedAdd trait ready for you to use.