1#![no_std]
8
9pub mod prelude {
18 #[allow(deprecated)]
19 pub use crate::{Extend as _, Truncate as _, Widen as _};
20}
21
22mod sealed {
23 pub trait Integer {}
24
25 macro_rules! impl_integer {
26 ($($t:ty)*) => {$(
27 impl Integer for $t {}
28 )*};
29 }
30
31 impl Integer for isize {}impl_integer! {
32 u8 u16 u32 u64 u128 usize
33 i8 i16 i32 i64 i128 isize
34 }
35
36 #[deprecated(since = "0.2.2", note = "use `WidenTargetSealed` instead")]
37 pub trait ExtendTargetSealed<T> {
38 #[deprecated(since = "0.2.2", note = "use `widen` instead")]
39 fn extend(self) -> T;
40 }
41
42 pub trait WidenTargetSealed<T> {
43 fn widen(self) -> T;
44 }
45
46 pub trait TruncateTargetSealed<T> {
47 fn truncate(self) -> T;
48 fn saturating_truncate(self) -> T;
49 fn checked_truncate(self) -> Option<T>;
50 }
51}
52
53#[deprecated(since = "0.2.2", note = "use `WidenTarget` instead")]
58#[allow(deprecated)]
59pub trait ExtendTarget<T>: sealed::ExtendTargetSealed<T> {}
60
61pub trait WidenTarget<T>: sealed::WidenTargetSealed<T> {}
66
67pub trait TruncateTarget<T>: sealed::TruncateTargetSealed<T> {}
72
73pub trait Widen: sealed::Integer {
91 fn widen<T>(self) -> T
93 where
94 Self: WidenTarget<T>;
95}
96
97impl<T: sealed::Integer> Widen for T {
98 fn widen<U>(self) -> U
99 where
100 T: WidenTarget<U>,
101 {
102 sealed::WidenTargetSealed::widen(self)
103 }
104}
105
106#[deprecated(since = "0.2.2", note = "use `Widen` instead")]
124#[allow(deprecated)]
125pub trait Extend: sealed::Integer {
126 fn extend<T>(self) -> T
128 where
129 Self: ExtendTarget<T>;
130}
131
132#[allow(deprecated)]
133impl<T: sealed::Integer> Extend for T {
134 fn extend<U>(self) -> U
135 where
136 T: ExtendTarget<U>,
137 {
138 sealed::ExtendTargetSealed::extend(self)
139 }
140}
141
142pub trait Truncate: sealed::Integer {
198 fn truncate<T>(self) -> T
201 where
202 Self: TruncateTarget<T>;
203
204 fn saturating_truncate<T>(self) -> T
207 where
208 Self: TruncateTarget<T>;
209
210 fn checked_truncate<T>(self) -> Option<T>
213 where
214 Self: TruncateTarget<T>;
215}
216
217impl<T: sealed::Integer> Truncate for T {
218 fn truncate<U>(self) -> U
219 where
220 T: TruncateTarget<U>,
221 {
222 sealed::TruncateTargetSealed::truncate(self)
223 }
224
225 fn saturating_truncate<U>(self) -> U
226 where
227 T: TruncateTarget<U>,
228 {
229 sealed::TruncateTargetSealed::saturating_truncate(self)
230 }
231
232 fn checked_truncate<U>(self) -> Option<U>
233 where
234 T: TruncateTarget<U>,
235 {
236 sealed::TruncateTargetSealed::checked_truncate(self)
237 }
238}
239
240macro_rules! impl_widen {
241 ($($from:ty => $($to:ty),+;)*) => {$($(
242 const _: () = assert!(
243 core::mem::size_of::<$from>() <= core::mem::size_of::<$to>(),
244 concat!(
245 "cannot widen ",
246 stringify!($from),
247 " to ",
248 stringify!($to),
249 " because ",
250 stringify!($from),
251 " is larger than ",
252 stringify!($to)
253 )
254 );
255
256 #[allow(deprecated)]
257 impl sealed::ExtendTargetSealed<$to> for $from {
258 #[inline]
259 fn extend(self) -> $to {
260 self as _
261 }
262 }
263
264 impl sealed::WidenTargetSealed<$to> for $from {
265 #[inline]
266 fn widen(self) -> $to {
267 self as _
268 }
269 }
270
271 #[allow(deprecated)]
272 impl ExtendTarget<$to> for $from {}
273 impl WidenTarget<$to> for $from {}
274 )+)*};
275}
276
277macro_rules! impl_truncate {
278 ($($($from:ty),+ => $to:ty;)*) => {$($(
279 const _: () = assert!(
280 core::mem::size_of::<$from>() >= core::mem::size_of::<$to>(),
281 concat!(
282 "cannot truncate ",
283 stringify!($from),
284 " to ",
285 stringify!($to),
286 " because ",
287 stringify!($from),
288 " is smaller than ",
289 stringify!($to)
290 )
291 );
292
293 impl sealed::TruncateTargetSealed<$to> for $from {
294 #[inline]
295 fn truncate(self) -> $to {
296 self as _
297 }
298
299 #[inline]
300 fn saturating_truncate(self) -> $to {
301 if self > <$to>::MAX as _ {
302 <$to>::MAX
303 } else if self < <$to>::MIN as _ {
304 <$to>::MIN
305 } else {
306 self as _
307 }
308 }
309
310 #[inline]
311 fn checked_truncate(self) -> Option<$to> {
312 if self > <$to>::MAX as _ || self < <$to>::MIN as _ {
313 None
314 } else {
315 Some(self as _)
316 }
317 }
318 }
319
320 impl TruncateTarget<$to> for $from {}
321 )+)*};
322}
323
324const _: () =
if !(core::mem::size_of::<isize>() <= core::mem::size_of::<isize>()) {
{
::core::panicking::panic_fmt(format_args!("cannot widen isize to isize because isize is larger than isize"));
}
};
#[allow(deprecated)]
impl sealed::ExtendTargetSealed<isize> for isize {
#[inline]
fn extend(self) -> isize { self as _ }
}
impl sealed::WidenTargetSealed<isize> for isize {
#[inline]
fn widen(self) -> isize { self as _ }
}
#[allow(deprecated)]
impl ExtendTarget<isize> for isize { }
impl WidenTarget<isize> for isize {}impl_widen! {
325 u8 => u8, u16, u32, u64, u128, usize;
326 u16 => u16, u32, u64, u128, usize;
327 u32 => u32, u64, u128;
328 u64 => u64, u128;
329 u128 => u128;
330 usize => usize;
331
332 i8 => i8, i16, i32, i64, i128, isize;
333 i16 => i16, i32, i64, i128, isize;
334 i32 => i32, i64, i128;
335 i64 => i64, i128;
336 i128 => i128;
337 isize => isize;
338}
339
340const _: () =
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 {
#[inline]
fn truncate(self) -> isize { self as _ }
#[inline]
fn saturating_truncate(self) -> isize {
if self > <isize>::MAX as _ {
<isize>::MAX
} else if self < <isize>::MIN as _ { <isize>::MIN } else { self as _ }
}
#[inline]
fn checked_truncate(self) -> Option<isize> {
if self > <isize>::MAX as _ || self < <isize>::MIN as _ {
None
} else { Some(self as _) }
}
}
impl TruncateTarget<isize> for isize {}impl_truncate! {
341 u8, u16, u32, u64, u128, usize => u8;
342 u16, u32, u64, u128, usize => u16;
343 u32, u64, u128 => u32;
344 u64, u128 => u64;
345 u128 => u128;
346 usize => usize;
347
348 i8, i16, i32, i64, i128, isize => i8;
349 i16, i32, i64, i128, isize => i16;
350 i32, i64, i128 => i32;
351 i64, i128 => i64;
352 i128 => i128;
353 isize => isize;
354}