1use crate::bounded_integer;
6
7bounded_integer! {
8 #[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
13 pub struct BoundedStruct { -8..8 }
19}
20
21bounded_integer! {
22 #[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
27 pub enum BoundedEnum { -8..8 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38
39 macro_rules! test_range {
40 ($fn:ident, $bounded:ident) => {
41 #[test]
42 fn $fn() {
43 assert_eq!($bounded::MIN_VALUE, -8);
44 assert_eq!($bounded::MAX_VALUE, 7);
45 assert_eq!($bounded::MIN.get(), -8);
46 assert_eq!($bounded::MAX.get(), 7);
47
48 assert!($bounded::in_range(0));
49 assert!($bounded::in_range(-8));
50 assert!(!$bounded::in_range(-9));
51 assert!($bounded::in_range(7));
52 assert!(!$bounded::in_range(8));
53
54 assert_eq!($bounded::default().get(), 0);
55 }
56 };
57 }
58
59 macro_rules! test_saturating {
60 ($fn:ident, $bounded:ident) => {
61 #[test]
62 fn $fn() {
63 assert_eq!($bounded::new_saturating(0).get(), 0);
64 assert_eq!($bounded::new_saturating(-8).get(), -8);
65 assert_eq!($bounded::new_saturating(-9).get(), -8);
66 assert_eq!($bounded::new_saturating(i8::MIN).get(), -8);
67 assert_eq!($bounded::new_saturating(7).get(), 7);
68 assert_eq!($bounded::new_saturating(8).get(), 7);
69 assert_eq!($bounded::new_saturating(i8::MAX).get(), 7);
70 }
71 };
72 }
73
74 macro_rules! test_arithmetic {
75 ($fn:ident, $bounded:ident) => {
76 #[test]
77 fn $fn() {
78 assert_eq!($bounded::new(7).unwrap().abs().get(), 7);
79 assert_eq!($bounded::new(-7).unwrap().abs().get(), 7);
80 assert_eq!($bounded::new(-2).unwrap().pow(3).get(), -8);
81 assert_eq!($bounded::new(-5).unwrap().div_euclid(3).get(), -2);
82 assert_eq!($bounded::new(-5).unwrap().rem_euclid(3).get(), 1);
83 assert_eq!(($bounded::new(-5).unwrap() + 2).get(), -3);
84 assert_eq!(($bounded::new(3).unwrap() - 7).get(), -4);
85 assert_eq!(($bounded::new(-2).unwrap() * 3).get(), -6);
86 assert_eq!(($bounded::new(7).unwrap() / 3).get(), 2);
87 assert_eq!(($bounded::new(7).unwrap() % 3).get(), 1);
88 assert_eq!(-2 + $bounded::new(-8).unwrap(), -10);
89 }
90 };
91 }
92
93 macro_rules! test_iter {
94 ($fn:ident, $bounded:ident) => {
95 #[test]
96 fn $fn() {
97 fn b(&n: &i8) -> $bounded {
98 $bounded::new(n).unwrap()
99 }
100
101 assert_eq!([3, 2, 1].iter().map(b).sum::<$bounded>().get(), 6);
102 assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<$bounded>().get(), 5);
103 assert_eq!([7, 6, 4].iter().map(b).sum::<i8>(), 17);
104 assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<i8>(), 5);
105
106 assert_eq!([1, 3, 2, 1].iter().map(b).product::<$bounded>().get(), 6);
107 assert_eq!([1, 3, 2, 1, 0].iter().map(b).product::<$bounded>().get(), 0);
108 assert_eq!([-2, -3, -1].iter().map(b).product::<$bounded>().get(), -6);
109 assert_eq!([3, 3].iter().map(b).product::<i8>(), 9);
110 }
111 };
112 }
113
114 macro_rules! test_parse {
115 ($fn:ident, $bounded:ident) => {
116 #[test]
117 fn $fn() {
118 use crate::ParseErrorKind::*;
119
120 assert_eq!("0".parse::<$bounded>().unwrap().get(), 0);
121 assert_eq!("-0".parse::<$bounded>().unwrap().get(), 0);
122 assert_eq!("+0".parse::<$bounded>().unwrap().get(), 0);
123 assert_eq!("3".parse::<$bounded>().unwrap().get(), 3);
124 assert_eq!("-8".parse::<$bounded>().unwrap().get(), -8);
125 assert_eq!("+7".parse::<$bounded>().unwrap().get(), 7);
126 assert_eq!($bounded::from_str_radix("0110", 2).unwrap().get(), 6);
127 assert_eq!($bounded::from_str_radix("-0111", 2).unwrap().get(), -7);
128 assert_eq!($bounded::from_str_radix("12", 4).unwrap().get(), 6);
129 assert_eq!($bounded::from_str_radix("+2", 36).unwrap().get(), 2);
130
131 assert_eq!("".parse::<$bounded>().unwrap_err().kind(), NoDigits);
132 assert_eq!("+".parse::<$bounded>().unwrap_err().kind(), NoDigits);
133 assert_eq!("-".parse::<$bounded>().unwrap_err().kind(), NoDigits);
134 assert_eq!("-9".parse::<$bounded>().unwrap_err().kind(), BelowMin);
135 assert_eq!("8".parse::<$bounded>().unwrap_err().kind(), AboveMax);
136 assert_eq!(
137 $bounded::from_str_radix("11", 7).unwrap_err().kind(),
138 AboveMax
139 );
140 assert_eq!("45483".parse::<$bounded>().unwrap_err().kind(), AboveMax);
141 assert_eq!("-01934".parse::<$bounded>().unwrap_err().kind(), BelowMin);
142
143 assert_eq!("++0".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
144 assert_eq!("--0".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
145 assert_eq!("O".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
146 assert_eq!("C".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
147 assert_eq!(
148 $bounded::from_str_radix("3", 2).unwrap_err().kind(),
149 InvalidDigit
150 );
151 }
152 };
153 }
154
155 test_range!(test_struct_range, BoundedStruct);
156 test_saturating!(test_struct_saturating, BoundedStruct);
157 test_arithmetic!(test_struct_arithmetic, BoundedStruct);
158 test_iter!(test_struct_iter, BoundedStruct);
159 test_parse!(test_struct_parse, BoundedStruct);
160
161 test_range!(test_enum_range, BoundedEnum);
162 test_saturating!(test_enum_saturating, BoundedEnum);
163 test_arithmetic!(test_enum_arithmetic, BoundedEnum);
164 test_iter!(test_enum_iter, BoundedEnum);
165 test_parse!(test_enum_parse, BoundedEnum);
166
167 #[allow(unused_imports)]
168 mod all_below_zero {
169 use super::bounded_integer;
170 bounded_integer! {
171 struct Struct { -400..=-203 }
172 }
173 bounded_integer! {
174 enum Enum { -500..=-483 }
175 }
176 }
177
178 mod correct_reprs {
179 use super::bounded_integer;
180 bounded_integer! {
181 struct ByteStruct { 0..256 }
182 }
183 const _: u8 = ByteStruct::MIN_VALUE;
184 bounded_integer! {
185 enum ByteEnum { 0..256 }
186 }
187 const _: u8 = ByteEnum::MIN_VALUE;
188
189 bounded_integer! {
190 struct SignedByteStruct { -128..128 }
191 }
192 const _: i8 = SignedByteStruct::MIN_VALUE;
193 bounded_integer! {
194 struct SignedByteEnum { -128..128 }
195 }
196 const _: i8 = SignedByteEnum::MIN_VALUE;
197 }
198}