use crate::bounded_integer;
bounded_integer! {
#[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
pub struct BoundedStruct { -8..8 }
}
bounded_integer! {
#[cfg_attr(feature = "step_trait", doc = "# #![feature(step_trait)]")]
pub enum BoundedEnum { -8..8 }
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! test_range {
($fn:ident, $bounded:ident) => {
#[test]
fn $fn() {
assert_eq!($bounded::MIN_VALUE, -8);
assert_eq!($bounded::MAX_VALUE, 7);
assert_eq!($bounded::MIN.get(), -8);
assert_eq!($bounded::MAX.get(), 7);
assert!($bounded::in_range(0));
assert!($bounded::in_range(-8));
assert!(!$bounded::in_range(-9));
assert!($bounded::in_range(7));
assert!(!$bounded::in_range(8));
assert_eq!($bounded::default().get(), 0);
}
};
}
macro_rules! test_saturating {
($fn:ident, $bounded:ident) => {
#[test]
fn $fn() {
assert_eq!($bounded::new_saturating(0).get(), 0);
assert_eq!($bounded::new_saturating(-8).get(), -8);
assert_eq!($bounded::new_saturating(-9).get(), -8);
assert_eq!($bounded::new_saturating(i8::MIN).get(), -8);
assert_eq!($bounded::new_saturating(7).get(), 7);
assert_eq!($bounded::new_saturating(8).get(), 7);
assert_eq!($bounded::new_saturating(i8::MAX).get(), 7);
}
};
}
macro_rules! test_arithmetic {
($fn:ident, $bounded:ident) => {
#[test]
fn $fn() {
assert_eq!($bounded::new(7).unwrap().abs().get(), 7);
assert_eq!($bounded::new(-7).unwrap().abs().get(), 7);
assert_eq!($bounded::new(-2).unwrap().pow(3).get(), -8);
assert_eq!($bounded::new(-5).unwrap().div_euclid(3).get(), -2);
assert_eq!($bounded::new(-5).unwrap().rem_euclid(3).get(), 1);
assert_eq!(($bounded::new(-5).unwrap() + 2).get(), -3);
assert_eq!(($bounded::new(3).unwrap() - 7).get(), -4);
assert_eq!(($bounded::new(-2).unwrap() * 3).get(), -6);
assert_eq!(($bounded::new(7).unwrap() / 3).get(), 2);
assert_eq!(($bounded::new(7).unwrap() % 3).get(), 1);
assert_eq!(-2 + $bounded::new(-8).unwrap(), -10);
}
};
}
macro_rules! test_iter {
($fn:ident, $bounded:ident) => {
#[test]
fn $fn() {
fn b(&n: &i8) -> $bounded {
$bounded::new(n).unwrap()
}
assert_eq!([3, 2, 1].iter().map(b).sum::<$bounded>().get(), 6);
assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<$bounded>().get(), 5);
assert_eq!([7, 6, 4].iter().map(b).sum::<i8>(), 17);
assert_eq!([-8, 3, 7, 5, -2].iter().map(b).sum::<i8>(), 5);
assert_eq!([1, 3, 2, 1].iter().map(b).product::<$bounded>().get(), 6);
assert_eq!([1, 3, 2, 1, 0].iter().map(b).product::<$bounded>().get(), 0);
assert_eq!([-2, -3, -1].iter().map(b).product::<$bounded>().get(), -6);
assert_eq!([3, 3].iter().map(b).product::<i8>(), 9);
}
};
}
macro_rules! test_parse {
($fn:ident, $bounded:ident) => {
#[test]
fn $fn() {
use crate::ParseErrorKind::*;
assert_eq!("0".parse::<$bounded>().unwrap().get(), 0);
assert_eq!("-0".parse::<$bounded>().unwrap().get(), 0);
assert_eq!("+0".parse::<$bounded>().unwrap().get(), 0);
assert_eq!("3".parse::<$bounded>().unwrap().get(), 3);
assert_eq!("-8".parse::<$bounded>().unwrap().get(), -8);
assert_eq!("+7".parse::<$bounded>().unwrap().get(), 7);
assert_eq!($bounded::from_str_radix("0110", 2).unwrap().get(), 6);
assert_eq!($bounded::from_str_radix("-0111", 2).unwrap().get(), -7);
assert_eq!($bounded::from_str_radix("12", 4).unwrap().get(), 6);
assert_eq!($bounded::from_str_radix("+2", 36).unwrap().get(), 2);
assert_eq!("".parse::<$bounded>().unwrap_err().kind(), NoDigits);
assert_eq!("+".parse::<$bounded>().unwrap_err().kind(), NoDigits);
assert_eq!("-".parse::<$bounded>().unwrap_err().kind(), NoDigits);
assert_eq!("-9".parse::<$bounded>().unwrap_err().kind(), BelowMin);
assert_eq!("8".parse::<$bounded>().unwrap_err().kind(), AboveMax);
assert_eq!(
$bounded::from_str_radix("11", 7).unwrap_err().kind(),
AboveMax
);
assert_eq!("45483".parse::<$bounded>().unwrap_err().kind(), AboveMax);
assert_eq!("-01934".parse::<$bounded>().unwrap_err().kind(), BelowMin);
assert_eq!("++0".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
assert_eq!("--0".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
assert_eq!("O".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
assert_eq!("C".parse::<$bounded>().unwrap_err().kind(), InvalidDigit);
assert_eq!(
$bounded::from_str_radix("3", 2).unwrap_err().kind(),
InvalidDigit
);
}
};
}
test_range!(test_struct_range, BoundedStruct);
test_saturating!(test_struct_saturating, BoundedStruct);
test_arithmetic!(test_struct_arithmetic, BoundedStruct);
test_iter!(test_struct_iter, BoundedStruct);
test_parse!(test_struct_parse, BoundedStruct);
test_range!(test_enum_range, BoundedEnum);
test_saturating!(test_enum_saturating, BoundedEnum);
test_arithmetic!(test_enum_arithmetic, BoundedEnum);
test_iter!(test_enum_iter, BoundedEnum);
test_parse!(test_enum_parse, BoundedEnum);
#[allow(unused_imports)]
mod all_below_zero {
use super::bounded_integer;
bounded_integer! {
struct Struct { -400..=-203 }
}
bounded_integer! {
enum Enum { -500..=-483 }
}
}
mod correct_reprs {
use super::bounded_integer;
bounded_integer! {
struct ByteStruct { 0..256 }
}
const _: u8 = ByteStruct::MIN_VALUE;
bounded_integer! {
enum ByteEnum { 0..256 }
}
const _: u8 = ByteEnum::MIN_VALUE;
bounded_integer! {
struct SignedByteStruct { -128..128 }
}
const _: i8 = SignedByteStruct::MIN_VALUE;
bounded_integer! {
struct SignedByteEnum { -128..128 }
}
const _: i8 = SignedByteEnum::MIN_VALUE;
}
}