1 | use crate::{ |
2 | RangedI128, RangedI16, RangedI32, RangedI64, RangedI8, RangedIsize, RangedU128, RangedU16, |
3 | RangedU32, RangedU64, RangedU8, RangedUsize, |
4 | }; |
5 | |
6 | macro_rules! declare_traits { |
7 | ($($trait_name:ident),* $(,)?) => {$( |
8 | pub(crate) trait $trait_name { |
9 | const ASSERT: (); |
10 | } |
11 | )*}; |
12 | } |
13 | |
14 | macro_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 | |
57 | macro_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 | |
78 | macro_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 | |
92 | declare_traits![ |
93 | RangeIsValid, |
94 | AbsIsSafe, |
95 | NegIsSafe, |
96 | ExpandIsValid, |
97 | NarrowIsValid, |
98 | StaticIsValid, |
99 | ]; |
100 | |
101 | impl_traits_for_signed! { |
102 | RangedI8 i8, |
103 | RangedI16 i16, |
104 | RangedI32 i32, |
105 | RangedI64 i64, |
106 | RangedI128 i128, |
107 | RangedIsize isize, |
108 | } |
109 | |
110 | impl_traits_for_unsigned! { |
111 | RangedU8 u8, |
112 | RangedU16 u16, |
113 | RangedU32 u32, |
114 | RangedU64 u64, |
115 | RangedU128 u128, |
116 | RangedUsize usize, |
117 | } |
118 | |