I'm trying to make the following function generic. It currently uses u8::BITS but I want if a HashMap<&str, u32> is passed then use u32::BITS instead.
fn to_flag<'a>(
attack: &'a str,
attack_to_flag: &mut HashMap<&'a str, u8>,
) -> Result<T, Box<dyn Error>> {
let n = attack_to_flag.len() as u32;
match n < u8::BITS {
true => Ok(*attack_to_flag.entry(attack).or_insert(1 << n)),
false => Err(Box::<dyn Error>::from(
"More than 8 attacks; u8 insufficient.",
)),
}
}
In C++ I used to do map.mapped_type to get the type. Another approach I tried:
fn to_flag<'a, T>(
attack: &'a str,
attack_to_flag: &mut HashMap<&'a str, T>,
) -> Result<T, Box<dyn Error>> {
let n = attack_to_flag.len() as u32;
match n < T::BITS {
true => Ok(*attack_to_flag.entry(attack).or_insert(1 << n)),
false => Err(Box::<dyn Error>::from(
"More than 8 attacks; u8 insufficient.",
)),
}
}
But the compiler, understandably, complains
error[E0599]: no associated item named `BITS` found for type parameter `T` in the current scope
--> src\main.rs:41:16
|
41 | match n < T::BITS {
| ^^^^ associated item not found in `T`
error[E0308]: mismatched types
--> src\main.rs:42:56
|
36 | fn to_flag<'a, T>(
| - this type parameter
...
42 | true => Ok(*attack_to_flag.entry(attack).or_insert(1 << n)),
| --------- ^^^^^^ expected type parameter `T`, found integer
| |
| arguments to this function are incorrect
|
= note: expected type parameter `T`
found type `{integer}`
I was unable to find an Integer trait. What are my options?