deranged/
traits.rs

1//! Declaration and implementation of traits used for const assertions.
2
3use crate::{
4    RangedI128, RangedI16, RangedI32, RangedI64, RangedI8, RangedIsize, RangedU128, RangedU16,
5    RangedU32, RangedU64, RangedU8, RangedUsize,
6};
7
8/// Declare a series of traits that will be used for const assertions.
9macro_rules! declare_traits {
10    ($($trait_name:ident),* $(,)?) => {$(
11        pub(crate) trait $trait_name {
12            const ASSERT: ();
13        }
14    )*};
15}
16
17/// Implements traits that are common to all integer types.
18macro_rules! impl_traits_for_all {
19    ($($ranged_ty:ident $inner_ty:ident),* $(,)?) => {$(
20        impl<const MIN: $inner_ty, const MAX: $inner_ty> RangeIsValid for $ranged_ty<MIN, MAX> {
21            const ASSERT: () = assert!(MIN <= MAX);
22        }
23
24        impl<
25            const CURRENT_MIN: $inner_ty,
26            const CURRENT_MAX: $inner_ty,
27            const NEW_MIN: $inner_ty,
28            const NEW_MAX: $inner_ty,
29        > ExpandIsValid for ($ranged_ty<CURRENT_MIN, CURRENT_MAX>, $ranged_ty<NEW_MIN, NEW_MAX>) {
30            const ASSERT: () = {
31                assert!(NEW_MIN <= CURRENT_MIN);
32                assert!(NEW_MAX >= CURRENT_MAX);
33            };
34        }
35
36        impl<
37            const CURRENT_MIN: $inner_ty,
38            const CURRENT_MAX: $inner_ty,
39            const NEW_MIN: $inner_ty,
40            const NEW_MAX: $inner_ty,
41        > NarrowIsValid for ($ranged_ty<CURRENT_MIN, CURRENT_MAX>, $ranged_ty<NEW_MIN, NEW_MAX>) {
42            const ASSERT: () = {
43                assert!(NEW_MIN >= CURRENT_MIN);
44                assert!(NEW_MAX <= CURRENT_MAX);
45            };
46        }
47
48        impl<
49            const VALUE: $inner_ty,
50            const MIN: $inner_ty,
51            const MAX: $inner_ty,
52        > StaticIsValid for ($ranged_ty<MIN, VALUE>, $ranged_ty<VALUE, MAX>) {
53            const ASSERT: () = {
54                assert!(VALUE >= MIN);
55                assert!(VALUE <= MAX);
56            };
57        }
58    )*};
59}
60
61/// Implement traits that are common to all signed integer types.
62macro_rules! impl_traits_for_signed {
63    ($($ranged_ty:ident $inner_ty:ident),* $(,)?) => {$(
64        impl<const MIN: $inner_ty, const MAX: $inner_ty> AbsIsSafe for $ranged_ty<MIN, MAX> {
65            const ASSERT: () = {
66                assert!(MIN != <$inner_ty>::MIN);
67                assert!(-MIN <= MAX);
68            };
69        }
70
71        impl<const MIN: $inner_ty, const MAX: $inner_ty> NegIsSafe for $ranged_ty<MIN, MAX> {
72            const ASSERT: () = {
73                assert!(MIN != <$inner_ty>::MIN);
74                assert!(-MIN <= MAX);
75                assert!(-MAX >= MIN);
76            };
77        }
78
79        impl_traits_for_all!($ranged_ty $inner_ty);
80    )*};
81}
82
83/// Implement traits that are common to all unsigned integer types.
84macro_rules! impl_traits_for_unsigned {
85    ($($ranged_ty:ident $inner_ty:ident),* $(,)?) => {$(
86        impl<const MIN: $inner_ty, const MAX: $inner_ty> AbsIsSafe for $ranged_ty<MIN, MAX> {
87            const ASSERT: () = ();
88        }
89
90        impl<const MIN: $inner_ty, const MAX: $inner_ty> NegIsSafe for $ranged_ty<MIN, MAX> {
91            const ASSERT: () = assert!(MAX == 0);
92        }
93
94        impl_traits_for_all!($ranged_ty $inner_ty);
95    )*};
96}
97
98declare_traits![
99    RangeIsValid,
100    AbsIsSafe,
101    NegIsSafe,
102    ExpandIsValid,
103    NarrowIsValid,
104    StaticIsValid,
105];
106
107impl_traits_for_signed! {
108    RangedI8 i8,
109    RangedI16 i16,
110    RangedI32 i32,
111    RangedI64 i64,
112    RangedI128 i128,
113    RangedIsize isize,
114}
115
116impl_traits_for_unsigned! {
117    RangedU8 u8,
118    RangedU16 u16,
119    RangedU32 u32,
120    RangedU64 u64,
121    RangedU128 u128,
122    RangedUsize usize,
123}