/rust/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.2.0/src/lib.rs
Line | Count | Source |
1 | | //! `num_conv` is a crate to convert between integer types without using `as` casts. This provides |
2 | | //! better certainty when refactoring, makes the exact behavior of code more explicit, and allows |
3 | | //! using turbofish syntax. |
4 | | |
5 | | #![no_std] |
6 | | |
7 | | /// Anonymously import all extension traits. |
8 | | /// |
9 | | /// This allows you to use the methods without worrying about polluting the namespace or importing |
10 | | /// them individually. |
11 | | /// |
12 | | /// ```rust |
13 | | /// use num_conv::prelude::*; |
14 | | /// ``` |
15 | | pub mod prelude { |
16 | | pub use crate::{Extend as _, Truncate as _}; |
17 | | } |
18 | | |
19 | | mod 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! { |
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 | | |
42 | | /// A type that can be used with turbofish syntax in [`Extend::extend`]. |
43 | | /// |
44 | | /// It is unlikely that you will want to use this trait directly. You are probably looking for the |
45 | | /// [`Extend`] trait. |
46 | | pub trait ExtendTarget<T>: sealed::ExtendTargetSealed<T> {} |
47 | | |
48 | | /// A type that can be used with turbofish syntax in [`Truncate::truncate`]. |
49 | | /// |
50 | | /// It is unlikely that you will want to use this trait directly. You are probably looking for the |
51 | | /// [`Truncate`] trait. |
52 | | pub trait TruncateTarget<T>: sealed::TruncateTargetSealed<T> {} |
53 | | |
54 | | /// Extend to an integer of the same size or larger, preserving its value. |
55 | | /// |
56 | | /// ```rust |
57 | | /// # use num_conv::Extend; |
58 | | /// assert_eq!(0_u8.extend::<u16>(), 0_u16); |
59 | | /// assert_eq!(0_u16.extend::<u32>(), 0_u32); |
60 | | /// assert_eq!(0_u32.extend::<u64>(), 0_u64); |
61 | | /// assert_eq!(0_u64.extend::<u128>(), 0_u128); |
62 | | /// ``` |
63 | | /// |
64 | | /// ```rust |
65 | | /// # use num_conv::Extend; |
66 | | /// assert_eq!((-1_i8).extend::<i16>(), -1_i16); |
67 | | /// assert_eq!((-1_i16).extend::<i32>(), -1_i32); |
68 | | /// assert_eq!((-1_i32).extend::<i64>(), -1_i64); |
69 | | /// assert_eq!((-1_i64).extend::<i128>(), -1_i128); |
70 | | /// ``` |
71 | | pub trait Extend: sealed::Integer { |
72 | | /// Extend an integer to an integer of the same size or larger, preserving its value. |
73 | | fn extend<T>(self) -> T |
74 | | where |
75 | | Self: ExtendTarget<T>; |
76 | | } |
77 | | |
78 | | impl<T: sealed::Integer> Extend for T { |
79 | 0 | fn extend<U>(self) -> U |
80 | 0 | where |
81 | 0 | T: ExtendTarget<U>, |
82 | | { |
83 | 0 | sealed::ExtendTargetSealed::extend(self) |
84 | 0 | } Unexecuted instantiation: <u8 as num_conv::Extend>::extend::<usize> Unexecuted instantiation: <_ as num_conv::Extend>::extend::<_> |
85 | | } |
86 | | |
87 | | /// Truncate to an integer of the same size or smaller, preserving the least significant bits. |
88 | | /// |
89 | | /// ```rust |
90 | | /// # use num_conv::Truncate; |
91 | | /// assert_eq!(u16::MAX.truncate::<u8>(), u8::MAX); |
92 | | /// assert_eq!(u32::MAX.truncate::<u16>(), u16::MAX); |
93 | | /// assert_eq!(u64::MAX.truncate::<u32>(), u32::MAX); |
94 | | /// assert_eq!(u128::MAX.truncate::<u64>(), u64::MAX); |
95 | | /// ``` |
96 | | /// |
97 | | /// ```rust |
98 | | /// # use num_conv::Truncate; |
99 | | /// assert_eq!((-1_i16).truncate::<i8>(), -1_i8); |
100 | | /// assert_eq!((-1_i32).truncate::<i16>(), -1_i16); |
101 | | /// assert_eq!((-1_i64).truncate::<i32>(), -1_i32); |
102 | | /// assert_eq!((-1_i128).truncate::<i64>(), -1_i64); |
103 | | /// ``` |
104 | | pub trait Truncate: sealed::Integer { |
105 | | /// Truncate an integer to an integer of the same size or smaller, preserving the least |
106 | | /// significant bits. |
107 | | fn truncate<T>(self) -> T |
108 | | where |
109 | | Self: TruncateTarget<T>; |
110 | | } |
111 | | |
112 | | impl<T: sealed::Integer> Truncate for T { |
113 | 0 | fn truncate<U>(self) -> U |
114 | 0 | where |
115 | 0 | T: TruncateTarget<U>, |
116 | | { |
117 | 0 | sealed::TruncateTargetSealed::truncate(self) |
118 | 0 | } Unexecuted instantiation: <u32 as num_conv::Truncate>::truncate::<u8> Unexecuted instantiation: <_ as num_conv::Truncate>::truncate::<_> |
119 | | } |
120 | | |
121 | | macro_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 | 0 | fn extend(self) -> $to { |
139 | 0 | self as _ |
140 | 0 | } Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<u8>>::extend Unexecuted instantiation: <i32 as num_conv::sealed::ExtendTargetSealed<i128>>::extend Unexecuted instantiation: <i64 as num_conv::sealed::ExtendTargetSealed<i64>>::extend Unexecuted instantiation: <i64 as num_conv::sealed::ExtendTargetSealed<i128>>::extend Unexecuted instantiation: <i128 as num_conv::sealed::ExtendTargetSealed<i128>>::extend Unexecuted instantiation: <isize as num_conv::sealed::ExtendTargetSealed<isize>>::extend Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<u16>>::extend Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<u32>>::extend Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<u64>>::extend Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<u128>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<i8>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<i16>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<i32>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<i64>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<i128>>::extend Unexecuted instantiation: <i8 as num_conv::sealed::ExtendTargetSealed<isize>>::extend Unexecuted instantiation: <i16 as num_conv::sealed::ExtendTargetSealed<i16>>::extend Unexecuted instantiation: <i16 as num_conv::sealed::ExtendTargetSealed<i32>>::extend Unexecuted instantiation: <i16 as num_conv::sealed::ExtendTargetSealed<i64>>::extend Unexecuted instantiation: <i16 as num_conv::sealed::ExtendTargetSealed<i128>>::extend Unexecuted instantiation: <i16 as num_conv::sealed::ExtendTargetSealed<isize>>::extend Unexecuted instantiation: <i32 as num_conv::sealed::ExtendTargetSealed<i32>>::extend Unexecuted instantiation: <i32 as num_conv::sealed::ExtendTargetSealed<i64>>::extend Unexecuted instantiation: <u8 as num_conv::sealed::ExtendTargetSealed<usize>>::extend Unexecuted instantiation: <u16 as num_conv::sealed::ExtendTargetSealed<u16>>::extend Unexecuted instantiation: <u16 as num_conv::sealed::ExtendTargetSealed<u32>>::extend Unexecuted instantiation: <u16 as num_conv::sealed::ExtendTargetSealed<u64>>::extend Unexecuted instantiation: <u16 as num_conv::sealed::ExtendTargetSealed<u128>>::extend Unexecuted instantiation: <u16 as num_conv::sealed::ExtendTargetSealed<usize>>::extend Unexecuted instantiation: <u32 as num_conv::sealed::ExtendTargetSealed<u32>>::extend Unexecuted instantiation: <u32 as num_conv::sealed::ExtendTargetSealed<u64>>::extend Unexecuted instantiation: <u32 as num_conv::sealed::ExtendTargetSealed<u128>>::extend Unexecuted instantiation: <u64 as num_conv::sealed::ExtendTargetSealed<u64>>::extend Unexecuted instantiation: <u64 as num_conv::sealed::ExtendTargetSealed<u128>>::extend Unexecuted instantiation: <u128 as num_conv::sealed::ExtendTargetSealed<u128>>::extend Unexecuted instantiation: <usize as num_conv::sealed::ExtendTargetSealed<usize>>::extend |
141 | | } |
142 | | |
143 | | impl ExtendTarget<$to> for $from {} |
144 | | )+)*}; |
145 | | } |
146 | | |
147 | | macro_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 | 0 | fn truncate(self) -> $to { |
165 | 0 | self as _ |
166 | 0 | } Unexecuted instantiation: <u128 as num_conv::sealed::TruncateTargetSealed<u32>>::truncate Unexecuted instantiation: <u64 as num_conv::sealed::TruncateTargetSealed<u64>>::truncate Unexecuted instantiation: <u128 as num_conv::sealed::TruncateTargetSealed<u64>>::truncate Unexecuted instantiation: <u128 as num_conv::sealed::TruncateTargetSealed<u128>>::truncate Unexecuted instantiation: <usize as num_conv::sealed::TruncateTargetSealed<usize>>::truncate Unexecuted instantiation: <i8 as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <i16 as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <i32 as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <i64 as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <i128 as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <isize as num_conv::sealed::TruncateTargetSealed<i8>>::truncate Unexecuted instantiation: <i16 as num_conv::sealed::TruncateTargetSealed<i16>>::truncate Unexecuted instantiation: <i32 as num_conv::sealed::TruncateTargetSealed<i16>>::truncate Unexecuted instantiation: <u8 as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <u16 as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <u32 as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <u64 as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <u128 as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <usize as num_conv::sealed::TruncateTargetSealed<u8>>::truncate Unexecuted instantiation: <u16 as num_conv::sealed::TruncateTargetSealed<u16>>::truncate Unexecuted instantiation: <u32 as num_conv::sealed::TruncateTargetSealed<u16>>::truncate Unexecuted instantiation: <u64 as num_conv::sealed::TruncateTargetSealed<u16>>::truncate Unexecuted instantiation: <u128 as num_conv::sealed::TruncateTargetSealed<u16>>::truncate Unexecuted instantiation: <usize as num_conv::sealed::TruncateTargetSealed<u16>>::truncate Unexecuted instantiation: <u32 as num_conv::sealed::TruncateTargetSealed<u32>>::truncate Unexecuted instantiation: <u64 as num_conv::sealed::TruncateTargetSealed<u32>>::truncate Unexecuted instantiation: <i64 as num_conv::sealed::TruncateTargetSealed<i16>>::truncate Unexecuted instantiation: <i128 as num_conv::sealed::TruncateTargetSealed<i16>>::truncate Unexecuted instantiation: <isize as num_conv::sealed::TruncateTargetSealed<i16>>::truncate Unexecuted instantiation: <i32 as num_conv::sealed::TruncateTargetSealed<i32>>::truncate Unexecuted instantiation: <i64 as num_conv::sealed::TruncateTargetSealed<i32>>::truncate Unexecuted instantiation: <i128 as num_conv::sealed::TruncateTargetSealed<i32>>::truncate Unexecuted instantiation: <i64 as num_conv::sealed::TruncateTargetSealed<i64>>::truncate Unexecuted instantiation: <i128 as num_conv::sealed::TruncateTargetSealed<i64>>::truncate Unexecuted instantiation: <i128 as num_conv::sealed::TruncateTargetSealed<i128>>::truncate Unexecuted instantiation: <isize as num_conv::sealed::TruncateTargetSealed<isize>>::truncate |
167 | | } |
168 | | |
169 | | impl TruncateTarget<$to> for $from {} |
170 | | )+)*}; |
171 | | } |
172 | | |
173 | | 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 | | |
189 | | 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 | | } |