I have a type, that can be represented as f32, without NaN or infinity or negative values and with a maximum value, a trivial example could be people heights in meters, so I'm using the new type pattern to represent it:
struct Height(f32);
impl TryFrom<f32> for Height {
type Error = &'static str;
fn try_from(value: f32) -> Result<Self, Self::Error> {
if value.is_infinite() || value.is_sign_negative() || value > 3. {
return Err("value was infinite");
}
Ok(Height(value))
}
}
What I don't like is when I have to deal with an array of these, because it should be declared like
let vec = vec![Height::try_from(3.).unwrap(), Height::try_from(2.).unwrap()];
adding a lot of boilerplate. Also when I need to pass it to a function that accepts &[f32], it's a bit of a pain to convert.
What's the idiomatic way of handling a situation like this?
Edit: if it's changed 300. to 3., since in the example I'm talking about people heights in meters.
Maybe a macro to call
Height::try_from(x).unwrap()
?Something like
h!(3.0)
As for the function that wants &[f32], to safely convert from [Height] -> [f32] you would have to construct a new slice using the f32's from the Heights which is O(n) so not too fast.
A better question is why does the function want &[f32] and can you change it?