ufix/
cast.rs

1use crate::{Error, Result};
2
3/// Similar to `core::convert::From`
4pub trait Cast<T> {
5    /// Convert value from `T`
6    fn cast(value: T) -> Self;
7}
8
9/// Similar to `core::convert::TryFrom`
10pub trait TryCast<T>: Sized {
11    /// Convert value from `T`
12    fn try_cast(value: T) -> Result<Self>;
13}
14
15macro_rules! cast_impls {
16    ($($type:ident),*) => {
17        $(
18            cast_impls!(@$type: u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
19            #[cfg(feature = "i128")]
20            cast_impls!(@$type: u128, i128);
21        )*
22    };
23
24    (@$type:ident: $($from:ident),*) => {
25        $(
26            impl Cast<$from> for $type {
27                fn cast(value: $from) -> Self {
28                    value as Self
29                }
30            }
31        )*
32    };
33}
34
35cast_impls!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
36
37#[cfg(feature = "i128")]
38cast_impls!(u128, i128);
39
40macro_rules! try_cast_impls {
41    ($($(#[$($meta:meta)*])* $from:ident => $type:ident $(($($check:ident),*))*;)*) => {
42        $(
43            $(#[$($meta)*])*
44            impl TryCast<$from> for $type {
45                fn try_cast(value: $from) -> Result<Self> {
46                    $($(try_cast_impls!{@$check value: $from => $type})*)*
47                    Ok(value as Self)
48                }
49            }
50        )*
51    };
52
53    (@max $val:ident: $from:ident => $type:ident) => {
54        if $val > $type::MAX as $from {
55            return Err(Error::TooBig);
56        }
57    };
58
59    (@min $val:ident: $from:ident => $type:ident) => {
60        if $val < $type::MIN as $from {
61            return Err(Error::TooSmall);
62        }
63    };
64}
65
66try_cast_impls! {
67    // u8 => u
68    u8 => u8;
69    u8 => u16;
70    u8 => u32;
71    u8 => u64;
72
73    // u8 => i
74    u8 => i8 (max);
75    u8 => i16;
76    u8 => i32;
77    u8 => i64;
78
79    // u8 => f
80    u8 => f32;
81    u8 => f64;
82
83    // i8 => u
84    i8 => u8 (min);
85    i8 => u16 (min);
86    i8 => u32 (min);
87    i8 => u64 (min);
88
89    // i8 => i
90    i8 => i8;
91    i8 => i16;
92    i8 => i32;
93    i8 => i64;
94
95    // u8 => f
96    i8 => f32;
97    i8 => f64;
98
99    // u16 => u
100    u16 => u8 (max);
101    u16 => u16;
102    u16 => u32;
103    u16 => u64;
104
105    // u16 => i
106    u16 => i8 (max);
107    u16 => i16 (max);
108    u16 => i32;
109    u16 => i64;
110
111    // u16 => f
112    u16 => f32;
113    u16 => f64;
114
115    // i16 => u
116    i16 => u8 (min, max);
117    i16 => u16 (min);
118    i16 => u32 (min);
119    i16 => u64 (min);
120
121    // i16 => i
122    i16 => i8 (min, max);
123    i16 => i16;
124    i16 => i32;
125    i16 => i64;
126
127    // i16 => f
128    i16 => f32;
129    i16 => f64;
130
131    // u32 => u
132    u32 => u8 (max);
133    u32 => u16 (max);
134    u32 => u32;
135    u32 => u64;
136
137    // u32 => i
138    u32 => i8 (max);
139    u32 => i16 (max);
140    u32 => i32 (max);
141    u32 => i64;
142
143    // u32 => f
144    u32 => f32;
145    u32 => f64;
146
147    // i32 => u
148    i32 => u8 (min, max);
149    i32 => u16 (min, max);
150    i32 => u32 (min);
151    i32 => u64 (min);
152
153    // i32 => i
154    i32 => i8 (min, max);
155    i32 => i16 (min, max);
156    i32 => i32;
157    i32 => i64;
158
159    // i32 => f
160    i32 => f32;
161    i32 => f64;
162
163    // u64 => u
164    u64 => u8 (max);
165    u64 => u16 (max);
166    u64 => u32 (max);
167    u64 => u64;
168
169    // u64 => i
170    u64 => i8 (max);
171    u64 => i16 (max);
172    u64 => i32 (max);
173    u64 => i64 (max);
174
175    // u64 => f
176    u64 => f32;
177    u64 => f64;
178
179    // i64 => u
180    i64 => u8 (min, max);
181    i64 => u16 (min, max);
182    i64 => u32 (min, max);
183    i64 => u64 (min);
184
185    // i64 => i
186    i64 => i8 (min, max);
187    i64 => i16 (min, max);
188    i64 => i32 (min, max);
189    i64 => i64;
190
191    // i64 => f
192    i64 => f32;
193    i64 => f64;
194
195    /// f32 => u
196    f32 => u8 (min, max);
197    f32 => u16 (min, max);
198    f32 => u32 (min, max);
199    f32 => u64 (min, max);
200
201    /// f32 => i
202    f32 => i8 (min, max);
203    f32 => i16 (min, max);
204    f32 => i32 (min, max);
205    f32 => i64 (min, max);
206
207    /// f32 => f
208    f32 => f32;
209    f32 => f64;
210
211    /// f32 => u
212    f64 => u8 (min, max);
213    f64 => u16 (min, max);
214    f64 => u32 (min, max);
215    f64 => u64 (min, max);
216
217    /// f32 => i
218    f64 => i8 (min, max);
219    f64 => i16 (min, max);
220    f64 => i32 (min, max);
221    f64 => i64 (min, max);
222
223    /// f32 => f
224    f64 => f32 (min, max);
225    f64 => f64;
226}
227
228#[cfg(feature = "i128")]
229try_cast_impls! {
230    u8 => u128;
231    u8 => i128;
232
233    i8 => u128 (min);
234    i8 => i128;
235
236    u16 => u128;
237    u16 => i128;
238
239    i16 => u128 (min);
240    i16 => i128;
241
242    u32 => u128;
243    u32 => i128;
244
245    i32 => u128 (min);
246    i32 => i128;
247
248    u64 => u128;
249    u64 => i128;
250
251    i64 => u128 (min);
252    i64 => i128;
253
254    f32 => u128 (min, max);
255    f32 => i128 (min, max);
256
257    f64 => u128 (min, max);
258    f64 => i128 (min, max);
259
260    // u128 => u
261    u128 => u8 (max);
262    u128 => u16 (max);
263    u128 => u32 (max);
264    u128 => u64 (max);
265    u128 => u128;
266
267    // u128 => i
268    u128 => i8 (max);
269    u128 => i16 (max);
270    u128 => i32 (max);
271    u128 => i64 (max);
272    u128 => i128 (max);
273
274    // u128 => f
275    u128 => f32;
276    u128 => f64;
277
278    // i128 => u
279    i128 => u8 (min, max);
280    i128 => u16 (min, max);
281    i128 => u32 (min, max);
282    i128 => u64 (min, max);
283    i128 => u128 (min);
284
285    // i128 => i
286    i128 => i8 (min, max);
287    i128 => i16 (min, max);
288    i128 => i32 (min, max);
289    i128 => i64 (min, max);
290    i128 => i128;
291
292    // i128 => f
293    i128 => f32;
294    i128 => f64;
295}