An idiom in C code is to have an array of nullable values which is
partially initialized via `{ [0] = x, [7] = y}`. Because Rust expects
everything to be fully initialized, it does not have this idiom by
default.`sparse_array!` allows declaration of `[Option<T>; _]` constants to allow Rust code to more easily mimic the safe version of this pattern. Signed-off-by: Matthew Maurer <[email protected]> Co-developed-by: Gary Guo <[email protected]> Signed-off-by: Gary Guo <[email protected]> --- rust/kernel/slice.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/rust/kernel/slice.rs b/rust/kernel/slice.rs index ca2cde13506196d46c9169aa6e4ab2ac42af6f5b..826b6f77f0d07775bd22837cc1773b59ec96936c 100644 --- a/rust/kernel/slice.rs +++ b/rust/kernel/slice.rs @@ -47,3 +47,40 @@ fn as_flattened_mut(&mut self) -> &mut [T] { self.flatten_mut() } } + +/// Create a sparse array of `[Option<T>; _]`. +/// +/// This is intended for use when C code would write `{ [0] = x, [7] = y}` to perform partial +/// initialization of an array. +/// +/// # Example +/// ``` +/// use kernel::sparse_array; +/// const FOO: &[Option<usize>] = &sparse_array! { +/// 0: 10, +/// 7: 16, +/// }; +/// assert_eq!(FOO[0], Some(10)); +/// assert_eq!(FOO[1], None); +/// assert_eq!(FOO[7], Some(16)); +/// ``` +#[macro_export] +macro_rules! sparse_array { + ($( + $index:literal: $value:expr + ),* $(,)?) => {{ + const SIZE: usize = { + let mut size = 0; + $(if $index >= size { + size = $index + 1; + })* + size + }; + + const { + let mut arr = [None; SIZE]; + $(arr[$index] = Some($value);)* + arr + } + }} +} -- 2.53.0.rc2.204.g2597b5adb4-goog
