#[cfg(not(any(feature = "std", feature = "alloc")))]
compile_error!("expected either `std` or `alloc` to be enabled");
use core::mem::MaybeUninit;
#[cfg(feature = "std")]
use std::vec::IntoIter;
#[cfg(all(not(feature = "std"), feature = "alloc"))]
use alloc::{
boxed::Box,
vec::{IntoIter, Vec},
};
use non_empty_iter::{FromNonEmptyIterator, IntoNonEmptyIterator};
use non_zero_size::Size;
use thiserror::Error;
use crate::{
format,
iter::IntoNonEmptyIter,
slice::{EmptySlice, NonEmptyMaybeUninitSlice, NonEmptySlice},
vec::{EmptyVec, NonEmptyVec},
};
pub type NonEmptyBoxedSlice<T> = Box<NonEmptySlice<T>>;
pub type NonEmptyMaybeUninitBoxedSlice<T> = NonEmptyBoxedSlice<MaybeUninit<T>>;
pub type NonEmptyBoxedBytes = NonEmptyBoxedSlice<u8>;
pub const EMPTY_BOXED_SLICE: &str = "the boxed slice is empty";
#[derive(Error)]
#[error("{EMPTY_BOXED_SLICE}")]
#[cfg_attr(
feature = "diagnostics",
derive(miette::Diagnostic),
diagnostic(
code(non_empty_slice::boxed),
help("make sure the boxed slice is non-empty")
)
)]
pub struct EmptyBoxedSlice<T> {
boxed: Box<[T]>,
}
format::debug!(EmptyBoxedSlice, boxed);
pub type EmptyBoxedBytes = EmptyBoxedSlice<u8>;
impl<T> EmptyBoxedSlice<T> {
pub(crate) const fn new(boxed: Box<[T]>) -> Self {
Self { boxed }
}
#[must_use]
pub fn get(self) -> Box<[T]> {
self.boxed
}
#[must_use]
pub fn from_empty_vec(empty: EmptyVec<T>) -> Self {
Self::new(empty.get().into_boxed_slice())
}
#[must_use]
pub fn into_empty_vec(self) -> EmptyVec<T> {
EmptyVec::from_empty_boxed_slice(self)
}
}
impl<T> From<NonEmptyBoxedSlice<T>> for Box<[T]> {
fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
boxed.into_boxed_slice()
}
}
impl<T> TryFrom<Box<[T]>> for NonEmptyBoxedSlice<T> {
type Error = EmptyBoxedSlice<T>;
fn try_from(boxed: Box<[T]>) -> Result<Self, Self::Error> {
NonEmptySlice::from_boxed_slice(boxed)
}
}
impl<T> TryFrom<Vec<T>> for NonEmptyBoxedSlice<T> {
type Error = EmptyVec<T>;
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
let non_empty_vec = NonEmptyVec::new(vec)?;
Ok(non_empty_vec.into())
}
}
impl<T> From<NonEmptyBoxedSlice<T>> for Vec<T> {
fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
boxed.into_boxed_slice().into_vec()
}
}
impl<T> From<NonEmptyBoxedSlice<T>> for NonEmptyVec<T> {
fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
boxed.into_non_empty_vec()
}
}
impl<T> From<NonEmptyVec<T>> for NonEmptyBoxedSlice<T> {
fn from(non_empty: NonEmptyVec<T>) -> Self {
non_empty.into_non_empty_boxed_slice()
}
}
impl<T: Clone> TryFrom<&[T]> for NonEmptyBoxedSlice<T> {
type Error = EmptySlice;
fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
let non_empty_slice = NonEmptySlice::try_from_slice(slice)?;
Ok(non_empty_slice.into())
}
}
impl<T: Clone> TryFrom<&mut [T]> for NonEmptyBoxedSlice<T> {
type Error = EmptySlice;
fn try_from(slice: &mut [T]) -> Result<Self, Self::Error> {
let non_empty_slice = NonEmptySlice::try_from_mut_slice(slice)?;
Ok(non_empty_slice.into())
}
}
impl<T: Clone> From<&NonEmptySlice<T>> for NonEmptyBoxedSlice<T> {
fn from(non_empty: &NonEmptySlice<T>) -> Self {
non_empty.to_non_empty_vec().into_non_empty_boxed_slice()
}
}
impl<T: Clone> From<&mut NonEmptySlice<T>> for NonEmptyBoxedSlice<T> {
fn from(non_empty: &mut NonEmptySlice<T>) -> Self {
non_empty.to_non_empty_vec().into_non_empty_boxed_slice()
}
}
impl<T: Clone> Clone for NonEmptyBoxedSlice<T> {
fn clone(&self) -> Self {
self.to_non_empty_vec().into_non_empty_boxed_slice()
}
fn clone_from(&mut self, source: &Self) {
if self.len() == source.len() {
self.clone_from_non_empty_slice(source);
} else {
*self = source.clone();
}
}
}
impl<T> NonEmptySlice<T> {
pub fn from_boxed_slice(boxed: Box<[T]>) -> Result<Box<Self>, EmptyBoxedSlice<T>> {
if boxed.is_empty() {
return Err(EmptyBoxedSlice::new(boxed));
}
Ok(unsafe { Self::from_boxed_slice_unchecked(boxed) })
}
#[must_use]
pub unsafe fn from_boxed_slice_unchecked(boxed: Box<[T]>) -> Box<Self> {
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut Self) }
}
#[must_use]
pub fn into_boxed_slice(self: Box<Self>) -> Box<[T]> {
unsafe { Box::from_raw(Box::into_raw(self) as *mut [T]) }
}
#[must_use]
pub fn from_non_empty_vec(non_empty: NonEmptyVec<T>) -> Box<Self> {
unsafe { Self::from_boxed_slice_unchecked(non_empty.into_vec().into_boxed_slice()) }
}
#[must_use]
pub fn into_non_empty_vec(self: Box<Self>) -> NonEmptyVec<T> {
NonEmptyVec::from_non_empty_boxed_slice(self)
}
#[must_use]
pub fn new_uninit(len: Size) -> NonEmptyMaybeUninitBoxedSlice<T> {
let boxed = Box::new_uninit_slice(len.get());
unsafe { NonEmptySlice::from_boxed_slice_unchecked(boxed) }
}
}
impl<T> FromNonEmptyIterator<T> for NonEmptyBoxedSlice<T> {
fn from_non_empty_iter<I: IntoNonEmptyIterator<Item = T>>(iterable: I) -> Self {
let non_empty_vec = NonEmptyVec::from_non_empty_iter(iterable);
non_empty_vec.into_non_empty_boxed_slice()
}
}
impl<T> NonEmptyMaybeUninitSlice<T> {
#[must_use]
pub unsafe fn assume_init(self: Box<Self>) -> NonEmptyBoxedSlice<T> {
let boxed = unsafe { self.into_boxed_slice().assume_init() };
unsafe { NonEmptySlice::from_boxed_slice_unchecked(boxed) }
}
}
impl<T> NonEmptyVec<T> {
#[must_use]
pub fn from_non_empty_boxed_slice(non_empty: NonEmptyBoxedSlice<T>) -> Self {
unsafe { Self::new_unchecked(non_empty.into_boxed_slice().into_vec()) }
}
#[must_use]
pub fn into_non_empty_boxed_slice(self) -> NonEmptyBoxedSlice<T> {
NonEmptySlice::from_non_empty_vec(self)
}
#[must_use]
pub fn into_boxed_slice(self) -> Box<[T]> {
self.into_non_empty_boxed_slice().into_boxed_slice()
}
}
impl<T> IntoIterator for NonEmptyBoxedSlice<T> {
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.into_non_empty_vec().into_iter()
}
}
impl<T> IntoNonEmptyIterator for NonEmptyBoxedSlice<T> {
type IntoNonEmptyIter = IntoNonEmptyIter<T>;
fn into_non_empty_iter(self) -> Self::IntoNonEmptyIter {
self.into_non_empty_vec().into_non_empty_iter()
}
}