1#![no_std]
6
7pub mod prelude {
16 pub use crate::{Extend as _, Truncate as _};
17}
18
19mod sealed {
20 pub trait Integer {}
21
22 macro_rules! impl_integer {
23 ($($t:ty)*) => {$(
24 impl Integer for $t {}
25 )*};
26 }
27
28 impl Integer for isize {}impl_integer! {
29 u8 u16 u32 u64 u128 usize
30 i8 i16 i32 i64 i128 isize
31 }
32
33 pub trait ExtendTargetSealed<T> {
34 fn extend(self) -> T;
35 }
36
37 pub trait TruncateTargetSealed<T> {
38 fn truncate(self) -> T;
39 }
40}
41
42pub trait ExtendTarget<T>: sealed::ExtendTargetSealed<T> {}
47
48pub trait TruncateTarget<T>: sealed::TruncateTargetSealed<T> {}
53
54pub trait Extend: sealed::Integer {
72 fn extend<T>(self) -> T
74 where
75 Self: ExtendTarget<T>;
76}
77
78impl<T: sealed::Integer> Extend for T {
79 fn extend<U>(self) -> U
80 where
81 T: ExtendTarget<U>,
82 {
83 sealed::ExtendTargetSealed::extend(self)
84 }
85}
86
87pub trait Truncate: sealed::Integer {
105 fn truncate<T>(self) -> T
108 where
109 Self: TruncateTarget<T>;
110}
111
112impl<T: sealed::Integer> Truncate for T {
113 fn truncate<U>(self) -> U
114 where
115 T: TruncateTarget<U>,
116 {
117 sealed::TruncateTargetSealed::truncate(self)
118 }
119}
120
121macro_rules! impl_extend {
122 ($($from:ty => $($to:ty),+;)*) => {$($(
123 const _: () = assert!(
124 core::mem::size_of::<$from>() <= core::mem::size_of::<$to>(),
125 concat!(
126 "cannot extend ",
127 stringify!($from),
128 " to ",
129 stringify!($to),
130 " because ",
131 stringify!($from),
132 " is larger than ",
133 stringify!($to)
134 )
135 );
136
137 impl sealed::ExtendTargetSealed<$to> for $from {
138 fn extend(self) -> $to {
139 self as _
140 }
141 }
142
143 impl ExtendTarget<$to> for $from {}
144 )+)*};
145}
146
147macro_rules! impl_truncate {
148 ($($($from:ty),+ => $to:ty;)*) => {$($(
149 const _: () = assert!(
150 core::mem::size_of::<$from>() >= core::mem::size_of::<$to>(),
151 concat!(
152 "cannot truncate ",
153 stringify!($from),
154 " to ",
155 stringify!($to),
156 " because ",
157 stringify!($from),
158 " is smaller than ",
159 stringify!($to)
160 )
161 );
162
163 impl sealed::TruncateTargetSealed<$to> for $from {
164 fn truncate(self) -> $to {
165 self as _
166 }
167 }
168
169 impl TruncateTarget<$to> for $from {}
170 )+)*};
171}
172
173const _: () =
if !(core::mem::size_of::<isize>() <= core::mem::size_of::<isize>()) {
{
::core::panicking::panic_fmt(format_args!("cannot extend isize to isize because isize is larger than isize"));
}
};
impl sealed::ExtendTargetSealed<isize> for isize {
fn extend(self) -> isize { self as _ }
}
impl ExtendTarget<isize> for isize {}impl_extend! {
174 u8 => u8, u16, u32, u64, u128, usize;
175 u16 => u16, u32, u64, u128, usize;
176 u32 => u32, u64, u128;
177 u64 => u64, u128;
178 u128 => u128;
179 usize => usize;
180
181 i8 => i8, i16, i32, i64, i128, isize;
182 i16 => i16, i32, i64, i128, isize;
183 i32 => i32, i64, i128;
184 i64 => i64, i128;
185 i128 => i128;
186 isize => isize;
187}
188
189const _: () =
if !(core::mem::size_of::<isize>() >= core::mem::size_of::<isize>()) {
{
::core::panicking::panic_fmt(format_args!("cannot truncate isize to isize because isize is smaller than isize"));
}
};
impl sealed::TruncateTargetSealed<isize> for isize {
fn truncate(self) -> isize { self as _ }
}
impl TruncateTarget<isize> for isize {}impl_truncate! {
190 u8, u16, u32, u64, u128, usize => u8;
191 u16, u32, u64, u128, usize => u16;
192 u32, u64, u128 => u32;
193 u64, u128 => u64;
194 u128 => u128;
195 usize => usize;
196
197 i8, i16, i32, i64, i128, isize => i8;
198 i16, i32, i64, i128, isize => i16;
199 i32, i64, i128 => i32;
200 i64, i128 => i64;
201 i128 => i128;
202 isize => isize;
203}