If you are concerned with performance, leave it as is. You are already accepting all integer types. Conversion from strings should happen elsewhere. (as already mentioned by the other answers)
That said, to actually fulfill your request, here is a horribly inefficient but simple solution to your problem :)
pub fn prime<T>(val: T) -> bool
where
T: ToString,
{
let val: u64 = val.to_string().parse().unwrap();
for i in 2..val {
if val % i == 0 {
return false;
}
if i * i >= val {
break;
}
}
true
}
fn main() {
println!("{:?}", prime(17));
println!("{:?}", prime("17"));
println!("{:?}", prime(String::from("17")));
}
true
true
true
On a more serious note ... your own solution and all of the answers convert the input into another type.
If you skip that and instead use the given type directly, you could potentially get a speed boost.
For that to work, though, I had to switch from i * i >= val to ..=val.sqrt().
pub fn prime<T>(val: T) -> bool
where
T: num::PrimInt + num::integer::Roots,
{
let two = T::one() + T::one();
for i in num::range_inclusive(two, val.sqrt()) {
if val % i == T::zero() {
return false;
}
}
true
}
fn main() {
println!("{:?}", prime(17));
}
true
As a further note, you could rewrite the entire for loop with the all iterator method:
pub fn prime<T>(val: T) -> bool
where
T: num::PrimInt + num::integer::Roots,
{
let two = T::one() + T::one();
num::range_inclusive(two, val.sqrt()).all(|i| val % i != T::zero())
}
fn main() {
println!("{:?}", prime(17));
}
true