I would like a data structure that represents an array of values, but which only supports a specific set of sizes and enforces this at compile time. Something like:
struct MyArray<const N: usize>([u8; N]);
But such than N
can only be a specific set of values, not just any number representable by usize
. For example, I would like a struct can wrap either a [u8; 3]
, a [u8; 6]
, or a [u8; 9]
, but not a [u8; N]
for any other N
besides 3, 6, and 9. I need the enforcement of this constraint to be at compile time, and ideally part of the type system. Is this possible in Rust? Is there a standard pattern or crate for doing this?
Depending on your use case, you can also represent the custom array as an enum:
#[derive(Clone, Debug)]
enum MyArray<T> {
Three([T; 3]),
Six([T; 6]),
Nine([T; 9]),
}
fn main() {
let mut array = MyArray::<u8>::Six(Default::default());
if let MyArray::Three(_) = &array {
println!("Nope.");
}
if let MyArray::Six(array) = &mut array {
array
.iter_mut()
.enumerate()
.for_each(|(index, element)| *element = index as u8);
}
println!("{array:?}");
println!("Size: {}", std::mem::size_of::<MyArray<u8>>());
}
Caveat: This will not be as space efficient as the separate impls, due to the nature of enums (size of largest variant). However, if 9 bytes is the maximum size, I assume that this is not an issue in your case.