deranged/
traits.rs

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