#![no_std]
pub trait TryTruncate<T> {
fn try_truncate(self) -> Option<T>;
}
pub trait TryTruncateFrom<T>: Sized {
fn try_truncate_from(value: T) -> Option<Self>;
}
impl<Source, Dest> TryTruncateFrom<Source> for Dest
where
Source: TryTruncate<Dest>,
{
fn try_truncate_from(x: Source) -> Option<Self> {
x.try_truncate()
}
}
pub trait Chop<T> {
fn chop(self) -> T;
}
pub trait ChopFrom<T> {
fn chop_from(value: T) -> Self;
}
impl<Source, Dest> ChopFrom<Source> for Dest
where
Source: Chop<Dest>,
{
fn chop_from(x: Source) -> Self {
x.chop()
}
}
pub trait TruncateUnchecked<T> {
fn truncate_unchecked(self) -> T;
}
pub trait TruncateFromUnchecked<T> {
fn truncate_from_unchecked(value: T) -> Self;
}
impl<Source, Dest> TruncateFromUnchecked<Source> for Dest
where
Source: TruncateUnchecked<Dest>,
{
fn truncate_from_unchecked(x: Source) -> Self {
x.truncate_unchecked()
}
}
pub trait Shrink<T> {
fn shrink(self) -> T;
}
pub trait ShrinkFrom<T> {
fn shrink_from(value: T) -> Self;
}
impl<Source, Dest> ShrinkFrom<Source> for Dest
where
Source: Shrink<Dest>,
{
fn shrink_from(x: Source) -> Self {
x.shrink()
}
}
macro_rules! make_truncate {
($Source: ty, $Dest:ty) => {
impl TryTruncate<$Dest> for $Source {
#[track_caller]
#[inline]
fn try_truncate(self) -> Option<$Dest> {
use ::core::convert::TryFrom;
<$Dest>::try_from(self).ok()
}
}
impl Chop<$Dest> for $Source {
#[track_caller]
#[inline]
fn chop(self) -> $Dest {
use ::core::convert::TryFrom;
match <$Dest>::try_from(self) {
Ok(val) => val,
Err(_) => panic!("chop overflow"),
}
}
}
impl Shrink<$Dest> for $Source {
#[track_caller]
#[inline]
fn shrink(self) -> $Dest {
use ::core::convert::TryFrom;
match <$Dest>::try_from(self) {
Ok(val) => val,
Err(_) => {
if self < (<$Dest>::MIN) as $Source {
<$Dest>::MIN
} else {
<$Dest>::MAX
}
}
}
}
}
};
}
macro_rules! make_truncate_all {
($Source: ty, $Dest:ty) => {
impl TruncateUnchecked<$Dest> for $Source {
#[track_caller]
#[inline]
fn truncate_unchecked(self) -> $Dest {
self as $Dest
}
}
make_truncate!($Source, $Dest);
}
}
make_truncate_all!(usize, u8);
make_truncate_all!(usize, u16);
make_truncate_all!(usize, u32);
make_truncate_all!(u128, u8);
make_truncate_all!(u128, u16);
make_truncate_all!(u128, u32);
make_truncate_all!(u128, u64);
make_truncate_all!(u64, u8);
make_truncate_all!(u64, u16);
make_truncate_all!(u64, u32);
make_truncate_all!(u32, u8);
make_truncate_all!(u32, u16);
make_truncate_all!(u16, u8);
make_truncate_all!(u128, i8);
make_truncate_all!(u128, i16);
make_truncate_all!(u128, i32);
make_truncate_all!(u128, i64);
make_truncate_all!(u64, i8);
make_truncate_all!(u64, i16);
make_truncate_all!(u64, i32);
make_truncate_all!(u32, i8);
make_truncate_all!(u32, i16);
make_truncate_all!(u16, i8);
make_truncate!(i128, i64);
make_truncate!(i128, i32);
make_truncate!(i128, i16);
make_truncate!(i128, i8);
make_truncate!(i64, i8);
make_truncate!(i64, i16);
make_truncate!(i64, i32);
make_truncate!(i32, i8);
make_truncate!(i32, i16);
make_truncate!(i16, i8);
make_truncate!(i128, u64);
make_truncate!(i128, u32);
make_truncate!(i128, u16);
make_truncate!(i128, u8);
make_truncate!(i64, u8);
make_truncate!(i64, u16);
make_truncate!(i64, u32);
make_truncate!(i32, u8);
make_truncate!(i32, u16);
make_truncate!(i16, u8);