I have an enum called Magnitude:
pub enum Magnitude<T> {
/// A finite value
Finite(T),
/// Positive infinity
PosInfinite,
/// Negative infinity
NegInfinite,
}
and I want to implement From trait to be able to construct Magnitude from different types:
impl<T: Any> From<T> for Magnitude<T> {
fn from(value: T) -> Self {
if value.type_id() == TypeId::of::<f64>() {
unsafe {
let value_f64 = (&value as *const T).cast::<f64>().as_ref().unwrap().clone();
if value_f64 == f64::INFINITY {
Magnitude::PosInfinite
} else if value_f64 == f64::NEG_INFINITY {
Magnitude::NegInfinite
} else {
Magnitude::Finite(value)
}
}
} else if value.type_id() == TypeId::of::<f32>() {
unsafe {
let value_f32 = (&value as *const T).cast::<f32>().as_ref().unwrap().clone();
if value_f32 == f32::INFINITY {
Magnitude::PosInfinite
} else if value_f32 == f32::NEG_INFINITY {
Magnitude::NegInfinite
} else {
Magnitude::Finite(value)
}
}
} else {
Magnitude::Finite(value)
}
}
}
if value is checked to be of type f64 using type_id, how unsafe is it to cast it to f64?
it passes the test below but I don't know if it will work correctly all the time:
#[test]
fn f64_infinity() {
let pos_inf: Magnitude<f64> = f64::INFINITY.into();
let neg_inf: Magnitude<f64> = f64::NEG_INFINITY.into();
assert!(pos_inf.is_pos_infinite());
assert!(neg_inf.is_neg_infinite());
}