use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::collections::TryReserveError;
use alloc::vec::{self, Vec};
use core::borrow::{Borrow, BorrowMut};
use core::error::Error;
use core::fmt::{self, Debug, Display, Formatter};
use core::iter::repeat_with;
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut, RangeBounds};
use core::slice;
use crate::{ModifyError, slice_range};
pub type VecOne<T> = VecMin<T, 1>;
#[repr(transparent)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VecMin<T, const M: usize> {
vec: Vec<T>,
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
#[track_caller]
pub const fn assert_invariant(&self) {
assert!(self.vec.len() >= M);
}
#[inline]
#[track_caller]
pub const fn debug_assert_invariant(&self) {
debug_assert!(self.vec.len() >= M);
}
#[inline]
pub const fn minimum(&self) -> usize {
M
}
#[inline]
pub const fn is_minimum(&self) -> bool {
self.vec.len() == M
}
#[inline]
pub const fn min_slice(&self) -> &[T; M] {
self.split_at_min().0
}
#[inline]
pub const fn min_slice_mut(&mut self) -> &mut [T; M] {
self.split_at_min_mut().0
}
#[inline]
pub const fn split_at_min(&self) -> (&[T; M], &[T]) {
self.debug_assert_invariant();
let (min, extra) = unsafe { self.vec.as_slice().split_at_unchecked(M) };
let min = unsafe { &*(min.as_ptr() as *const [T; M]) };
(min, extra)
}
#[inline]
pub const fn split_at_min_mut(&mut self) -> (&mut [T; M], &mut [T]) {
self.debug_assert_invariant();
let (min, extra) = unsafe { self.vec.as_mut_slice().split_at_mut_unchecked(M) };
let min = unsafe { &mut *(min.as_mut_ptr() as *mut [T; M]) };
(min, extra)
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ConstructError<T, const M: usize>(pub Vec<T>);
impl<T: Debug, const M: usize> Display for ConstructError<T, M> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(
f,
"Length {} of {:?} is less than the minimum {}",
self.0.len(),
self.0,
M
)
}
}
impl<T: Debug, const M: usize> Error for ConstructError<T, M> {}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub const unsafe fn from_vec_unchecked(vec: Vec<T>) -> Self {
Self { vec }
}
#[inline]
pub const fn try_from_vec(vec: Vec<T>) -> Result<Self, ConstructError<T, M>> {
if vec.len() >= M {
Ok(unsafe { Self::from_vec_unchecked(vec) })
} else {
Err(ConstructError(vec))
}
}
#[inline]
pub fn try_new(vec: impl Into<Vec<T>>) -> Result<Self, ConstructError<T, M>> {
Self::try_from_vec(vec.into())
}
#[inline]
pub fn from_array(array: [T; M]) -> Self {
unsafe { Self::from_vec_unchecked(array.into()) }
}
#[inline]
pub fn collect(iter: impl IntoIterator<Item = T>) -> Result<Self, ConstructError<T, M>> {
let iter = iter.into_iter();
let (low, high) = iter.size_hint();
Self::collect_with_capacity(iter, high.unwrap_or(low).max(M))
}
#[inline]
pub fn collect_with_capacity(
iter: impl IntoIterator<Item = T>,
capacity: usize,
) -> Result<Self, ConstructError<T, M>> {
let mut vec = Vec::with_capacity(capacity);
vec.extend(iter);
Self::try_new(vec)
}
#[inline]
pub fn into_inner(self) -> Vec<T> {
self.vec
}
#[inline]
pub fn into_boxed_slice(self) -> Box<[T]> {
self.vec.into_boxed_slice()
}
#[inline]
pub fn leak(self) -> &'static mut [T] {
self.vec.leak()
}
}
impl<T: Default, const M: usize> Default for VecMin<T, M> {
#[inline]
fn default() -> Self {
Self {
vec: repeat_with(T::default).take(M).collect(),
}
}
}
impl<T, const M: usize> TryFrom<Vec<T>> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
Self::try_new(vec)
}
}
impl<T, const M: usize> From<VecMin<T, M>> for Vec<T> {
#[inline]
fn from(vec_min: VecMin<T, M>) -> Self {
vec_min.vec
}
}
impl<T, const M: usize> TryFrom<Box<[T]>> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(boxed_slice: Box<[T]>) -> Result<Self, Self::Error> {
Self::try_new(boxed_slice)
}
}
impl<T, const M: usize> From<VecMin<T, M>> for Box<[T]> {
#[inline]
fn from(vec_min: VecMin<T, M>) -> Self {
vec_min.vec.into_boxed_slice()
}
}
impl<T: Clone, const M: usize> TryFrom<&[T]> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
Self::try_new(slice)
}
}
impl<T: Clone, const M: usize> TryFrom<&mut [T]> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(slice: &mut [T]) -> Result<Self, Self::Error> {
Self::try_new(slice)
}
}
impl<T: Clone, const M: usize> TryFrom<Cow<'_, [T]>> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(cow: Cow<'_, [T]>) -> Result<Self, Self::Error> {
Self::try_new(cow)
}
}
impl<T, const N: usize, const M: usize> TryFrom<[T; N]> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(array: [T; N]) -> Result<Self, Self::Error> {
Self::try_new(array)
}
}
impl<T: Clone, const N: usize, const M: usize> TryFrom<&[T; N]> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(array: &[T; N]) -> Result<Self, Self::Error> {
Self::try_new(array)
}
}
impl<T: Clone, const N: usize, const M: usize> TryFrom<&mut [T; N]> for VecMin<T, M> {
type Error = ConstructError<T, M>;
#[inline]
fn try_from(array: &mut [T; N]) -> Result<Self, Self::Error> {
Self::try_new(array)
}
}
impl<T, const N: usize, const M: usize> TryFrom<VecMin<T, M>> for [T; N] {
type Error = VecMin<T, M>;
#[inline]
fn try_from(vec_min: VecMin<T, M>) -> Result<[T; N], Self::Error> {
vec_min
.vec
.try_into()
.map_err(|vec| unsafe { VecMin::from_vec_unchecked(vec) })
}
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub const fn as_slice(&self) -> &[T] {
self.vec.as_slice()
}
#[inline]
pub const fn as_mut_slice(&mut self) -> &mut [T] {
self.vec.as_mut_slice()
}
#[inline]
pub const fn as_ptr(&self) -> *const T {
self.vec.as_ptr()
}
#[inline]
pub const fn as_mut_ptr(&mut self) -> *mut T {
self.vec.as_mut_ptr()
}
#[inline]
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
self.vec.spare_capacity_mut()
}
}
impl<T, const M: usize> Deref for VecMin<T, M> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
self.vec.deref()
}
}
impl<T, const M: usize> DerefMut for VecMin<T, M> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.vec.deref_mut()
}
}
impl<T, const M: usize> AsRef<[T]> for VecMin<T, M> {
#[inline]
fn as_ref(&self) -> &[T] {
self.vec.as_ref()
}
}
impl<T, const M: usize> AsMut<[T]> for VecMin<T, M> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self.vec.as_mut()
}
}
impl<T, const M: usize> Borrow<[T]> for VecMin<T, M> {
#[inline]
fn borrow(&self) -> &[T] {
self.vec.borrow()
}
}
impl<T, const M: usize> BorrowMut<[T]> for VecMin<T, M> {
#[inline]
fn borrow_mut(&mut self) -> &mut [T] {
self.vec.borrow_mut()
}
}
impl<T, const M: usize> IntoIterator for VecMin<T, M> {
type Item = T;
type IntoIter = vec::IntoIter<T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
impl<'a, T: 'a, const M: usize> IntoIterator for &'a VecMin<T, M> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.vec.as_slice().iter()
}
}
impl<'a, T: 'a, const M: usize> IntoIterator for &'a mut VecMin<T, M> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.vec.as_mut_slice().iter_mut()
}
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub const fn capacity(&self) -> usize {
self.vec.capacity()
}
#[inline]
#[allow(clippy::len_without_is_empty)]
pub const fn len(&self) -> usize {
self.vec.len()
}
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.vec.reserve(additional);
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.vec.reserve_exact(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.vec.try_reserve(additional)
}
#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.vec.try_reserve_exact(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.vec.shrink_to_fit();
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.vec.shrink_to(min_capacity);
}
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub fn push(&mut self, item: T) {
self.vec.push(item);
}
#[inline]
pub fn insert(&mut self, index: usize, element: T) {
self.vec.insert(index, element);
}
#[inline]
pub fn append(&mut self, other: &mut Vec<T>) {
self.vec.append(other);
}
#[inline]
pub fn extend_from_slice(&mut self, other: &[T])
where
T: Clone,
{
self.vec.extend_from_slice(other);
}
#[inline]
pub fn extend_from_within<R>(&mut self, range: R)
where
R: RangeBounds<usize>,
T: Clone,
{
self.vec.extend_from_within(range);
}
}
impl<T, const M: usize> Extend<T> for VecMin<T, M> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.vec.extend(iter);
}
}
impl<'a, T: Copy, const M: usize> Extend<&'a T> for VecMin<T, M> {
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.vec.extend(iter);
}
}
impl<T, const M: usize> VecMin<T, M> {
#[inline]
pub fn pop_to_min(&mut self) -> Option<T> {
if self.vec.len() > M {
self.vec.pop()
} else {
None
}
}
#[inline]
pub fn pop_to_min_if(&mut self, pred: impl FnOnce(&mut T) -> bool) -> Option<T> {
if self.vec.len() > M {
self.vec.pop_if(pred)
} else {
None
}
}
#[inline]
#[must_use = "this operation may fail"]
pub fn remove(&mut self, index: usize) -> Result<T, ModifyError<M>> {
if self.vec.len() > M {
Ok(self.vec.remove(index))
} else {
Err(ModifyError)
}
}
#[inline]
#[must_use = "this operation may fail"]
pub fn swap_remove(&mut self, index: usize) -> Result<T, ModifyError<M>> {
if self.vec.len() > M {
Ok(self.vec.swap_remove(index))
} else {
Err(ModifyError)
}
}
#[inline]
#[must_use = "this operation may fail"]
pub fn truncate(&mut self, len: usize) -> Result<(), ModifyError<M>> {
if len >= M {
self.vec.truncate(len);
Ok(())
} else {
Err(ModifyError)
}
}
#[inline]
pub fn truncate_or_min(&mut self, len: usize) {
self.vec.truncate(len.max(M))
}
#[inline]
pub fn truncate_to_min(&mut self) {
self.vec.truncate(M);
}
#[inline]
#[must_use = "this operation may fail"]
pub fn resize(&mut self, new_len: usize, value: T) -> Result<(), ModifyError<M>>
where
T: Clone,
{
if new_len >= M {
self.vec.resize(new_len, value);
Ok(())
} else {
Err(ModifyError)
}
}
#[inline]
pub fn resize_or_min(&mut self, new_len: usize, value: T)
where
T: Clone,
{
self.vec.resize(new_len.max(M), value);
}
#[inline]
#[must_use = "this operation may fail"]
pub fn resize_with<F>(&mut self, new_len: usize, generator: F) -> Result<(), ModifyError<M>>
where
F: FnMut() -> T,
{
if new_len >= M {
self.vec.resize_with(new_len, generator);
Ok(())
} else {
Err(ModifyError)
}
}
#[inline]
pub fn resize_or_min_with<F>(&mut self, new_len: usize, generator: F)
where
F: FnMut() -> T,
{
self.vec.resize_with(new_len.max(M), generator);
}
#[must_use = "this operation may fail"]
pub fn drain<R>(&mut self, range: R) -> Result<vec::Drain<'_, T>, ModifyError<M>>
where
R: RangeBounds<usize>,
{
let drain_len = slice_range(&range, ..self.vec.len()).len();
let final_len = self.vec.len() - drain_len;
if final_len >= M {
Ok(self.vec.drain(range))
} else {
Err(ModifyError)
}
}
#[inline]
#[must_use = "this operation may fail"]
pub fn split_off(&mut self, at: usize) -> Result<Vec<T>, ModifyError<M>> {
if at >= M {
Ok(self.vec.split_off(at))
} else {
Err(ModifyError)
}
}
}