Split cast into cast and cast_lossy
There is a difference in intent between wishing to cast and truncate the value, and expecting the input to be within range. To make this clear, add separate `cast_lossy` and `cast_from_lossy` to indicate what that truncation is intended, leaving `cast` and `cast_from` to only be casts that expected not to truncate. Actually enforcing this at runtime is likely to have a cost, so just `debug_assert!` that `cast` doesn't truncate.
This commit is contained in:
parent
ab1038a32b
commit
beb34db83d
1 changed files with 19 additions and 0 deletions
|
|
@ -343,18 +343,30 @@ impl_h_int!(
|
|||
/// Trait to express (possibly lossy) casting of integers
|
||||
#[allow(unused)]
|
||||
pub trait CastInto<T: Copy>: Copy {
|
||||
/// By default, casts should be exact.
|
||||
fn cast(self) -> T;
|
||||
|
||||
/// Call for casts that are expected to truncate.
|
||||
fn cast_lossy(self) -> T;
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub trait CastFrom<T: Copy>: Copy {
|
||||
/// By default, casts should be exact.
|
||||
fn cast_from(value: T) -> Self;
|
||||
|
||||
/// Call for casts that are expected to truncate.
|
||||
fn cast_from_lossy(value: T) -> Self;
|
||||
}
|
||||
|
||||
impl<T: Copy, U: CastInto<T> + Copy> CastFrom<U> for T {
|
||||
fn cast_from(value: U) -> Self {
|
||||
value.cast()
|
||||
}
|
||||
|
||||
fn cast_from_lossy(value: U) -> Self {
|
||||
value.cast_lossy()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! cast_into {
|
||||
|
|
@ -364,6 +376,13 @@ macro_rules! cast_into {
|
|||
($ty:ty; $($into:ty),*) => {$(
|
||||
impl CastInto<$into> for $ty {
|
||||
fn cast(self) -> $into {
|
||||
// All we can really do to enforce casting rules is check the rules when in
|
||||
// debug mode.
|
||||
debug_assert!(<$into>::try_from(self).is_ok(), "failed cast from {self}");
|
||||
self as $into
|
||||
}
|
||||
|
||||
fn cast_lossy(self) -> $into {
|
||||
self as $into
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue