arch_into/
lib.rs

1#[cfg(all(target_pointer_width = "64", feature = "no-arch-64"))]
2compile_error!("arch-into is configured to not support 64-bits target");
3
4#[cfg(all(target_pointer_width = "32", feature = "no-arch-32"))]
5compile_error!("arch-into is configured to not support 32-bits target");
6
7pub trait ArchInto<T>: Sized {
8    fn arch_into(self) -> T;
9}
10
11pub trait ArchFrom<T>: Sized {
12    fn arch_from(value: T) -> Self;
13}
14
15#[allow(unused_macros)]
16macro_rules! define_try_conversion {
17    ($from:ty, $to:ty, $compare_through:ty) => {
18        paste::paste! {
19            #[track_caller]
20            const fn [<_check_boundaries_ $from _ $to>]() {
21                const_panic::concat_assert!{
22                    (<$from>::MAX as $compare_through) <= (<$to>::MAX as $compare_through) && (<$from>::MIN as $compare_through) >= (<$to>::MIN as $compare_through),
23                    "\n", <$from>::MAX, " <= ", <$to>::MAX, " (", (<$from>::MAX as $compare_through), " <= ", (<$to>::MAX  as $compare_through), ")"
24                }
25
26            }
27            const [<_CHECK_BOUNDARIES_ $from:upper _ $to:upper>]: () = [<_check_boundaries_ $from _ $to>]();
28        }
29
30        impl ArchInto<$to> for $from {
31            fn arch_into(self) -> $to {
32                self.try_into().unwrap()
33            }
34        }
35        impl ArchFrom<$from> for $to {
36            fn arch_from(value: $from) -> Self {
37                value.try_into().unwrap()
38            }
39        }
40    };
41}
42
43macro_rules! define_guaranteed_conversion {
44    ($from:ty, $to:ty) => {
45        impl ArchInto<$to> for $from {
46            fn arch_into(self) -> $to {
47                self.into()
48            }
49        }
50        impl ArchFrom<$from> for $to {
51            fn arch_from(value: $from) -> Self {
52                value.into()
53            }
54        }
55    };
56}
57
58#[cfg(all(not(feature = "no-arch-64"), not(feature = "no-arch-32")))]
59mod conversions_64bits_or_32bits {
60    // usize/isize is 32bits or 64bits
61
62    use super::*;
63
64    define_try_conversion!(usize, u64, u128);
65    define_try_conversion!(isize, i64, i128);
66
67    define_try_conversion!(usize, u128, u128);
68    define_try_conversion!(isize, i128, i128);
69
70    define_try_conversion!(u32, usize, u128);
71    define_try_conversion!(i32, isize, i128);
72}
73
74#[cfg(all(feature = "no-arch-32", not(feature = "no-arch-64")))]
75mod conversions_only_64bits {
76    // usize/isize is always 64bits
77
78    use super::*;
79
80    define_try_conversion!(usize, u64, u128);
81    define_try_conversion!(isize, i64, i128);
82
83    define_try_conversion!(usize, u128, u128);
84    define_try_conversion!(isize, i128, i128);
85
86    define_try_conversion!(u64, usize, u128);
87    define_try_conversion!(i64, isize, i128);
88
89    define_try_conversion!(u32, usize, u128);
90    define_try_conversion!(i32, isize, i128);
91}
92
93#[cfg(all(not(feature = "no-arch-32"), feature = "no-arch-64"))]
94mod conversions_only_32bits {
95    use super::*;
96
97    // usize/isize is always 32bits
98
99    define_try_conversion!(usize, u32, u128);
100    define_try_conversion!(isize, i32, i128);
101
102    define_try_conversion!(usize, u64, u128);
103    define_try_conversion!(isize, i64, i128);
104
105    define_try_conversion!(usize, u128, u128);
106    define_try_conversion!(isize, i128, i128);
107
108    define_try_conversion!(u32, usize, u128);
109    define_try_conversion!(i32, isize, i128);
110}
111
112define_guaranteed_conversion!(u16, usize);
113define_guaranteed_conversion!(i16, isize);
114
115define_guaranteed_conversion!(u8, usize);
116define_guaranteed_conversion!(i8, isize);