Expand description
Like From
, but supports fallible conversions
This trait is intented to be an extension over From
, also supporting
fallible conversions of numeric types.
Since Rust does not yet have stable support for handling conflicting
implementations (specialization or otherwise), only conversions between
the most important numeric types are supported for now.
The sister-trait Cast
supports “into” style usage.
Required Methods§
Provided Methods§
sourcefn conv(v: T) -> Self
fn conv(v: T) -> Self
Convert from T
to Self
This method must return the same result as Self::try_conv
where that
method succeeds, but differs in the handling of errors:
- In debug builds the method panics on error
- Otherwise, the method may panic or may return a different value,
but like with the
as
keyword all results must be well-defined and safe.
Default implementations use Self::try_conv
and panic on error.
Implementations provided by this library will panic in debug builds
or if the always_assert
feature flag is used, and otherwise will
behave identically to the as
keyword.
This mirrors the behaviour of Rust’s overflow checks on integer arithmetic in that it is a tool for diagnosing logic errors where success is expected.
Examples found in repository?
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
fn cast(self) -> T {
T::conv(self)
}
#[inline]
fn try_cast(self) -> Result<T> {
T::try_conv(self)
}
}
/// Like [`From`], but for approximate numerical conversions
///
/// On success, the result must be approximately the same as the input value:
/// the difference must be smaller than the precision of the target type.
/// For example, one may have `i32::conv_approx(1.9f32) = 1` or
/// `f32::conv_approx(1f64 + (f32::EPSILON as f64) / 2.0) = 1.0`.
///
/// Precise rounding mode should usually be truncation (round towards zero),
/// but this is not required. Use [`ConvFloat`] where a specific rounding mode
/// is required.
///
/// The sister-trait [`CastApprox`] supports "into" style usage.
pub trait ConvApprox<T>: Sized {
/// Try converting from `T` to `Self`, allowing approximation of value
///
/// This conversion may truncate excess precision not supported by the
/// target type, so long as the *value* is approximately equal, from the
/// point of view of precision of the target type.
///
/// This method should allow approximate conversion, but fail on input not
/// (approximately) in the target's range.
fn try_conv_approx(x: T) -> Result<Self>;
/// Converting from `T` to `Self`, allowing approximation of value
///
/// This method must return the same result as [`Self::try_conv_approx`]
/// where that method succeeds, but differs in the handling of errors:
///
/// - In debug builds the method panics on error
/// - Otherwise, the method may panic or may return a different value,
/// but like with the `as` keyword all results must be well-defined and
/// *safe*.
///
/// Default implementations use [`Self::try_conv_approx`] and panic on error.
/// Implementations provided by this library will panic in debug builds
/// or if the `always_assert` feature flag is used, and otherwise will
/// behave identically to the `as` keyword.
///
/// This mirrors the behaviour of Rust's overflow checks on integer
/// arithmetic in that it is a tool for diagnosing logic errors where
/// success is expected.
#[inline]
fn conv_approx(x: T) -> Self {
Self::try_conv_approx(x).unwrap_or_else(|e| {
panic!("ConvApprox::conv_approx(_) failed: {}", e);
})
}
}
// TODO(specialization): implement also where T: ConvFloat<S>
impl<S, T: Conv<S>> ConvApprox<S> for T {
#[inline]
fn try_conv_approx(x: S) -> Result<Self> {
T::try_conv(x)
}
#[inline]
fn conv_approx(x: S) -> Self {
T::conv(x)
}