From 6a8f7df5d12316166de405d9410ca9988a58430b Mon Sep 17 00:00:00 2001 From: Kristof Date: Fri, 28 Mar 2025 14:15:37 +0100 Subject: [PATCH] added from_array that allows you initialize an entire array of values with fairly compact syntax --- deranged/src/lib.rs | 22 ++++++++++++++++++++++ deranged/src/tests.rs | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/deranged/src/lib.rs b/deranged/src/lib.rs index 91b562e..c7fa493 100644 --- a/deranged/src/lib.rs +++ b/deranged/src/lib.rs @@ -952,6 +952,28 @@ macro_rules! impl_ranged { ) } } } + + /// Convert an array of plain integers into an array of RangedX. Useful for const initialization + /// when you have a lookup table with lots of values that are all in range. + /// eg + /// const CONST_ARRAY : [RangedU8<1,10>;10] = RangedU8<1,10>::from_array([1,2,3,4,5,6,7,8,9,10]).unwrap(); + /// + /// Returns None if any of the values are out of range, so the compile will fail at the unwrap if + /// any of the values are out of range. + pub const fn from_array(a: [$internal; N]) -> Option<[Self; N]> { + let mut r = [Self::MIN; N]; + let mut i = 0; + while i < N { + if let Some(x) = Self::new(a[i]) { + r[i] = x; + } else { + return None; + } + + i += 1; + } + Some(r) + } } impl $optional_type { diff --git a/deranged/src/tests.rs b/deranged/src/tests.rs index 3ea7530..785caa1 100644 --- a/deranged/src/tests.rs +++ b/deranged/src/tests.rs @@ -601,6 +601,25 @@ macro_rules! tests { assert_eq!($t::<5, 10>::try_from(11), Err(TryFromIntError)); )*} + #[test] + fn from_array() {$( + { + // Create array of 3 elements that's a const + const MYARR : [$t::<5, 10>; 3] = $t::<5, 10>::from_array([5,6,10]).unwrap(); + const EXPECTED_RESULT : [$t::<5,10>;3] = [ + $t::<5,10>::new_static::<5>(), + $t::<5,10>::new_static::<6>(), + $t::<5,10>::new_static::<10>()]; + + assert_eq!(MYARR, EXPECTED_RESULT); + } + + // if any element is out of range, the whole array is None + assert_eq!( + $t::<5, 10>::from_array([5,6,11]), + None); + )*} + #[test] fn from_str() {$( assert_eq!("10".parse::<$t<5, 10>>(), Ok($t::<5, 10>::MAX));