I am trying to convert Rc<Vec<F>> into into Rc<Vec<T>> where T and F are numeric types like u8, f32, f64, etc. As the vectors may be quite large, I would like to avoid copying them if F and T are the same type. I do not manage to find out how to do that. Something like this -- it does not compile as the type comparison T == F is invalid:
fn convert_vec<F: num::NumCast + Copy, T: num::NumCast + Copy>(data: &[F], undef: T) -> Vec<T> {
data.iter()
.map(|v| match T::from(*v) {
Some(x) => x,
None => undef,
})
.collect()
}
fn convert_rc_vec<F: num::NumCast + Copy, T: num::NumCast + Copy>(
data: &Rc<Vec<F>>,
undef: T,
) -> anyhow::Result<Rc<Vec<T>>> {
if (T == F) { // invalid
Ok(data.clone()) // invalid
} else {
Ok(Rc::new(convert_vec(data, undef)))
}
}
The vector that I need to convert from is the response from a server which first sends the data type (something like "u8", "f32", "f64", ...) and then the actual data. At present, I store the vector with these data in enum like
pub enum Values {
UInt8(Rc<Vec<u8>>),
Float32(Rc<Vec<f32>>),
Float64(Rc<Vec<f64>>),
// ...
}
At compile time, I do not know in which format the server will send the data, i.e. I do not know F in advance. I do know T in every case I use it, but T might be a different type depending on the use case.
Using specialized functions like convert_rc_vec_to_f32 it is easy to handle the case where clone() is best. But that requires a separate function for each T with almost identical text. I am trying to find a more elegant solution than writing a macro or more or less repeating the code 9 times.