lminc/helper/
mod.rs

1use core::{fmt, mem::MaybeUninit, ptr::addr_of_mut};
2
3/// Case-insensitive chars and strs
4pub mod case_insensitive;
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7/// Errors for [`try_collect_into_array`]
8pub enum CollectIntoArrayError {
9    /// The array to collect into was not large enough
10    ArrayNotLargeEnough,
11}
12
13impl fmt::Display for CollectIntoArrayError {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        match self {
16            Self::ArrayNotLargeEnough => {
17                write!(f, "The array to collect into was not large enough!")
18            }
19        }
20    }
21}
22
23#[cfg(feature = "std")]
24impl std::error::Error for CollectIntoArrayError {}
25
26/// Try to collect the iterator into an array
27///
28/// # Errors
29/// See [`CollectIntoArrayError`]
30pub fn try_collect_into_array<const N: usize, T>(
31    iterator: impl Iterator<Item = T>,
32) -> Result<[Option<T>; N], CollectIntoArrayError> {
33    // Create an uninitialised array
34    let mut array: MaybeUninit<[Option<T>; N]> = MaybeUninit::uninit();
35    let array_ptr = array.as_mut_ptr();
36
37    // Write each item to the array, returning if full
38    let mut index = 0;
39    for item in iterator {
40        unsafe {
41            ((*array_ptr)
42                .get_mut(index)
43                .ok_or(CollectIntoArrayError::ArrayNotLargeEnough)? as *mut Option<T>)
44                .write(Some(item));
45        };
46        index += 1;
47    }
48
49    // Fill the remainder of the array with None
50    (index..N).for_each(|i| unsafe { addr_of_mut!((*array_ptr)[i]).write(None) });
51
52    Ok(unsafe { array.assume_init() })
53}