bounded_integer/
examples.rs

1//! Examples of bounded integers generated by the [`bounded_integer!`] macro.
2//!
3//! This module is not present when using the crate.
4
5use crate::bounded_integer;
6
7bounded_integer! {
8    /// A bounded struct, implemented as a protected newtype.
9    ///
10    /// This was generated from:
11    /// ```
12#[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
13    /// # use bounded_integer::bounded_integer;
14    /// bounded_integer! {
15    ///     pub struct BoundedStruct { -8..8 }
16    /// }
17    /// ```
18    pub struct BoundedStruct { -8..8 }
19}
20
21bounded_integer! {
22    /// A bounded enum.
23    ///
24    /// This was generated from:
25    /// ```
26#[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
27    /// # use bounded_integer::bounded_integer;
28    /// bounded_integer! {
29    ///     pub enum BoundedEnum { -8..8 }
30    /// }
31    /// ```
32    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}