Checking value for primitives

Hello.

I need a function to check a value (type: i64).
If a value has not been exceeded then the function has to return an error.
I have to pass to the function _data_type.
How to improve this function?

fn check_integer<T, D>(value: T, _data_type: D) -> Result<(), String>
where 
T: ToPrimitive + Bounded + std::cmp::PartialOrd + Copy, 
D: Bounded + ToPrimitive
{
    let max = D::max_value().to_u64().unwrap();
    let v_u64 = value.to_u64().unwrap();
    if v_u64 > max { 
       return Err("Overload - value is too bigger".to_string());
    }
    Ok(())
}

My code:
Playground

You could consider use something like TryInto to do the trick

use std::convert::TryInto;
use std::fmt;

fn check_integer<D, T>(value: T) -> Result<(), String>
where
    T: TryInto<D>,
    T::Error: fmt::Display,
{
    value.try_into().map(|_| ()).map_err(|e| format!("{}", e))
}

fn main() {
    let x = 1025;
    let res = check_integer::<u8, _>(x);
    println!("{:?}", res);
    assert_eq!(res.is_err(), true);

    let x = 255;
    let res = check_integer::<u8, _>(x);
    println!("{:?}", res);
    assert_eq!(res.is_err(), false);
}

(playground)

Err("out of range integral type conversion attempted")
Ok(())

Also, you don’t need to pass an unused argument; instead specify the type on the function call with ::<…> as shown above.

Finally, one could question your choice of API here. What’s the reason to do the check_integer test? In case it is to make sure that a conversion succeeds, better just do the conversion directly than offering the check_function separately.

Note that my code above is probably suboptimal in case the type D is more complicated, e.g. if it allocates something. In such a case there could be too much overhead – if it’s just used for simple integer type like u8 then it’s fine.

You could also use Box<dyn Error> or anyhow::Error instead of String. (Example.) Or keep the custom error type for each conversion in place (which would, for integral types from std result in a TryFromIntError).

1 Like