use crate::{
Array, ElementNotFound, IndexOutOfBounds, MismatchedBounds, Storage, array_from_fn, is,
};
impl<T, const CAP: usize, S: Storage> Array<T, CAP, S> {
pub fn new(array: [T; CAP]) -> Self {
Self { data: array.into() }
}
pub fn from_fn<F: FnMut(usize) -> T>(f: F) -> Self {
Self { data: array_from_fn(f).into() }
}
}
impl<T, const CAP: usize, S: Storage> Array<T, CAP, S> {
#[must_use]
pub const fn capacity(&self) -> usize {
CAP
}
#[must_use]
pub fn as_slice(&self) -> &[T] {
self.data.as_slice()
}
#[must_use]
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.data.as_mut_slice()
}
pub fn fill(&mut self, element: T)
where
T: Clone,
{
self.iter_mut().for_each(|i| *i = element.clone());
}
pub fn fill_default(&mut self)
where
T: Default,
{
self.iter_mut().for_each(|i| *i = T::default());
}
}
impl<T: PartialEq, const CAP: usize, S: Storage> Array<T, CAP, S> {
#[must_use]
pub fn contains(&self, element: &T) -> bool {
self.iter().any(|n| n == element)
}
pub fn contains_from(&self, element: &T, start: usize) -> Result<bool, IndexOutOfBounds> {
is![start >= CAP, return Err(IndexOutOfBounds(Some(start)))];
Ok(self.iter().skip(start).any(|n| n == element))
}
pub fn contains_until(&self, element: &T, end: usize) -> Result<bool, IndexOutOfBounds> {
is![end >= CAP, return Err(IndexOutOfBounds(Some(end)))];
Ok(self.iter().take(end + 1).any(|n| n == element))
}
pub fn contains_between(
&self,
element: &T,
start: usize,
end: usize,
) -> Result<bool, MismatchedBounds> {
is![start >= CAP, return Err(MismatchedBounds::IndexOutOfBounds(Some(start)))];
is![end >= CAP, return Err(MismatchedBounds::IndexOutOfBounds(Some(end)))];
is![start > end, return Err(MismatchedBounds::MismatchedIndices)];
Ok(self.iter().skip(start).take(end - start + 1).any(|n| n == element))
}
pub fn find_index(&self, element: &T) -> Result<usize, ElementNotFound> {
self.iter()
.enumerate()
.find_map(|(i, n)| (n == element).then_some(i))
.ok_or(ElementNotFound)
}
}
impl<T, const CAP: usize, S: Storage> Array<Option<T>, CAP, S> {
#[must_use]
pub fn take(&mut self, index: usize) -> Option<T> {
self.get_mut(index)?.take()
}
#[must_use]
pub fn replace(&mut self, index: usize, value: T) -> Option<T> {
self.get_mut(index)?.replace(value)
}
pub fn unset(&mut self, index: usize) {
self[index] = None;
}
pub fn clear(&mut self) {
self.iter_mut().for_each(|i| *i = None);
}
#[must_use]
pub fn count_some(&self) -> usize {
self.iter().filter(|opt| opt.is_some()).count()
}
#[must_use]
pub fn count_none(&self) -> usize {
self.iter().filter(|opt| opt.is_none()).count()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.iter().all(|opt| opt.is_some())
}
#[must_use]
pub fn is_full(&self) -> bool {
self.iter().all(|opt| opt.is_some())
}
pub fn fill_none(&mut self, value: T)
where
T: Clone,
{
self.iter_mut().filter(|opt| opt.is_none()).for_each(|opt| *opt = Some(value.clone()));
}
pub fn first_none(&self) -> Result<usize, ElementNotFound> {
self.iter().position(|opt| opt.is_none()).ok_or(ElementNotFound)
}
pub fn first_none_ref(&self) -> Result<&Option<T>, ElementNotFound> {
self.iter().find(|opt| opt.is_none()).ok_or(ElementNotFound)
}
pub fn first_none_mut(&mut self) -> Result<&mut Option<T>, ElementNotFound> {
self.iter_mut().find(|opt| opt.is_none()).ok_or(ElementNotFound)
}
pub fn first_some(&self) -> Result<usize, ElementNotFound> {
self.iter().position(|opt| opt.is_some()).ok_or(ElementNotFound)
}
pub fn first_some_ref(&self) -> Result<&Option<T>, ElementNotFound> {
self.iter().find(|opt| opt.is_some()).ok_or(ElementNotFound)
}
pub fn first_some_mut(&mut self) -> Result<&mut Option<T>, ElementNotFound> {
self.iter_mut().find(|opt| opt.is_some()).ok_or(ElementNotFound)
}
}