use crate::{alloc::*, EmptyError, NonEmptySlice};
#[cfg(feature = "std")]
use core::num::NonZeroU8;
use core::{
cmp::Ordering,
fmt,
hash::{Hash, Hasher},
mem::MaybeUninit,
num::NonZeroUsize,
ops, ptr,
slice::{self, SliceIndex},
};
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
#[repr(transparent)]
pub struct NonEmptyVec<T> {
pub(crate) inner: Vec<T>,
}
impl<T> NonEmptyVec<T> {
#[must_use]
#[inline]
pub unsafe fn empty() -> Self {
NonEmptyVec { inner: Vec::new() }
}
#[must_use]
#[inline]
pub unsafe fn with_capacity(capacity: NonZeroUsize) -> Self {
NonEmptyVec {
inner: Vec::with_capacity(capacity.get()),
}
}
#[must_use]
#[inline]
#[track_caller]
pub unsafe fn new_unchecked(vec: Vec<T>) -> Self {
debug_assert!(
!vec.is_empty(),
"non-empty vector initialized with an empty vector"
);
NonEmptyVec { inner: vec }
}
#[inline]
pub fn new(vec: Vec<T>) -> Result<Self, EmptyError> {
(!vec.is_empty())
.then(|| unsafe { NonEmptyVec::new_unchecked(vec) })
.ok_or(EmptyError)
}
#[must_use]
#[inline]
pub unsafe fn from_raw_parts(
ptr: *mut T,
length: NonZeroUsize,
capacity: NonZeroUsize,
) -> Self {
let vec = Vec::from_raw_parts(ptr, length.get(), capacity.get());
NonEmptyVec::new_unchecked(vec)
}
#[must_use]
#[inline]
pub fn as_vec(&self) -> &Vec<T> {
&self.inner
}
#[must_use]
#[inline]
pub fn into_vec(self) -> Vec<T> {
self.inner
}
#[must_use]
#[inline]
pub fn capacity(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) }
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.inner.reserve(additional);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.inner.reserve_exact(additional);
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve(additional)
}
#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.inner.try_reserve_exact(additional)
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn shrink_to_fit(&mut self) {
self.inner.shrink_to_fit();
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.inner.shrink_to(min_capacity);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[must_use]
#[inline]
pub fn into_boxed_slice(self) -> Box<NonEmptySlice<T>> {
let b = self.inner.into_boxed_slice();
let raw = Box::into_raw(b) as *mut NonEmptySlice<T>;
unsafe { Box::from_raw(raw) }
}
#[inline]
pub fn truncate(&mut self, len: NonZeroUsize) {
self.inner.truncate(len.get());
}
#[must_use]
#[inline]
pub fn as_slice(&self) -> &NonEmptySlice<T> {
unsafe { NonEmptySlice::new_unchecked(&self.inner) }
}
#[must_use]
#[inline]
pub fn as_mut_slice(&mut self) -> &mut NonEmptySlice<T> {
unsafe { NonEmptySlice::new_mut_unchecked(&mut self.inner) }
}
#[must_use]
#[inline]
pub fn as_ptr(&self) -> *const T {
self.inner.as_ptr()
}
#[must_use]
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.inner.as_mut_ptr()
}
#[inline]
pub unsafe fn set_len(&mut self, new_len: NonZeroUsize) {
debug_assert!(new_len < self.capacity());
self.inner.set_len(new_len.get());
}
#[inline]
#[track_caller]
fn assert_nonempty(&self, method_name: &'static str) {
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
fn assert_failed(method_name: &'static str) {
panic!("{method_name} left the NonEmptyVec empty");
}
if cfg!(debug_assertions) && self.inner.is_empty() {
assert_failed(method_name);
}
}
#[must_use]
#[inline]
#[track_caller]
pub unsafe fn swap_remove(&mut self, index: usize) -> T {
let element = self.inner.swap_remove(index);
self.assert_nonempty("swap_remove");
element
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
#[track_caller]
pub fn insert(&mut self, index: usize, element: T) {
self.inner.insert(index, element);
}
#[must_use]
#[inline]
#[track_caller]
pub unsafe fn remove(&mut self, index: usize) -> T {
let element = self.inner.remove(index);
self.assert_nonempty("remove");
element
}
#[inline]
#[track_caller]
pub unsafe fn retain<F>(&mut self, f: F)
where
F: FnMut(&T) -> bool,
{
self.inner.retain(f);
self.assert_nonempty("retain");
}
#[inline]
#[track_caller]
pub unsafe fn retain_mut<F>(&mut self, f: F)
where
F: FnMut(&mut T) -> bool,
{
self.inner.retain_mut(f);
self.assert_nonempty("retain_mut");
}
#[inline]
pub fn dedup_by_key<F, K>(&mut self, key: F)
where
F: FnMut(&mut T) -> K,
K: PartialEq,
{
self.inner.dedup_by_key(key);
}
#[inline]
pub fn dedup_by<F>(&mut self, same_bucket: F)
where
F: FnMut(&mut T, &mut T) -> bool,
{
self.inner.dedup_by(same_bucket);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
#[track_caller]
pub fn push(&mut self, value: T) {
self.inner.push(value);
}
#[inline]
#[track_caller]
pub unsafe fn pop(&mut self) -> T {
let element = self.inner.pop().unwrap_unchecked();
self.assert_nonempty("pop");
element
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
#[track_caller]
pub fn append(&mut self, other: &mut Vec<T>) {
self.inner.append(other);
}
#[inline]
#[track_caller]
pub unsafe fn drain<R>(&mut self, range: R) -> vec::Drain<'_, T>
where
R: ops::RangeBounds<usize>,
{
#[must_use]
#[track_caller]
fn slice_range_hack<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
where
R: ops::RangeBounds<usize>,
{
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
const fn slice_start_index_overflow_fail() -> ! {
panic!("attempted to index slice from after maximum usize");
}
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
const fn slice_end_index_overflow_fail() -> ! {
panic!("attempted to index slice up to maximum usize");
}
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
const fn slice_index_order_fail() -> ! {
panic!("slice index start is larger than end");
}
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
const fn slice_end_index_len_fail() -> ! {
panic!("slice end index is out of range for slice");
}
let len = bounds.end;
let start = match range.start_bound() {
ops::Bound::Included(&n) => n,
ops::Bound::Excluded(&n) => n
.checked_add(1)
.unwrap_or_else(|| slice_start_index_overflow_fail()),
ops::Bound::Unbounded => 0,
};
let end = match range.end_bound() {
ops::Bound::Included(&n) => n
.checked_add(1)
.unwrap_or_else(|| slice_end_index_overflow_fail()),
ops::Bound::Excluded(&n) => n,
ops::Bound::Unbounded => len,
};
if start > end {
slice_index_order_fail();
}
if end > len {
slice_end_index_len_fail();
}
ops::Range { start, end }
}
#[cfg_attr(panic = "abort", inline)]
#[cfg_attr(not(panic = "abort"), inline(never))]
#[cold]
#[track_caller]
const fn assert_failed() -> ! {
panic!("attempted to drain the entire vector");
}
let len = self.inner.len();
let normalized_range = slice_range_hack(range, ..len);
if cfg!(debug_assertions)
&& normalized_range.start == 0
&& normalized_range.end == (len - 1)
{
assert_failed();
}
self.inner.drain(normalized_range)
}
#[must_use]
#[inline]
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[must_use = "use `.truncate()` if you don't need the other half"]
#[inline]
#[track_caller]
pub fn split_off(&mut self, at: NonZeroUsize) -> Vec<T> {
self.inner.split_off(at.get())
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn resize_with<F>(&mut self, new_len: NonZeroUsize, f: F)
where
F: FnMut() -> T,
{
self.inner.resize_with(new_len.get(), f);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[must_use]
#[inline]
pub fn leak<'a>(self) -> &'a mut NonEmptySlice<T> {
unsafe { NonEmptySlice::new_mut_unchecked(self.inner.leak()) }
}
#[must_use]
#[inline]
pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
self.inner.spare_capacity_mut()
}
}
impl<T: Clone> NonEmptyVec<T> {
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn resize(&mut self, new_len: NonZeroUsize, value: T) {
self.inner.resize(new_len.get(), value);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
pub fn extend_from_slice(&mut self, other: &[T]) {
self.inner.extend_from_slice(other);
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
#[inline]
#[track_caller]
pub fn extend_from_within<R>(&mut self, src: R)
where
R: ops::RangeBounds<usize>,
{
self.inner.extend_from_within(src);
}
}
impl<T: PartialEq> NonEmptyVec<T> {
#[inline]
pub fn dedup(&mut self) {
self.inner.dedup();
}
}
impl<T> fmt::Debug for NonEmptyVec<T>
where
T: fmt::Debug,
{
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, f)
}
}
impl<T> Clone for NonEmptyVec<T>
where
T: Clone,
{
#[inline]
fn clone(&self) -> Self {
let vec = self.inner.clone();
unsafe { NonEmptyVec::new_unchecked(vec) }
}
#[inline]
fn clone_from(&mut self, source: &Self) {
self.inner.clone_from(&source.inner);
}
}
impl<T> ops::Deref for NonEmptyVec<T> {
type Target = NonEmptySlice<T>;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<T> ops::DerefMut for NonEmptyVec<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
impl<T> AsRef<[T]> for NonEmptyVec<T> {
#[inline]
fn as_ref(&self) -> &[T] {
self.as_slice().as_ref()
}
}
impl<T> AsMut<[T]> for NonEmptyVec<T> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self.as_mut_slice().as_mut()
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> AsRef<NonEmptySlice<T>> for NonEmptyVec<T> {
#[inline]
fn as_ref(&self) -> &NonEmptySlice<T> {
self.as_slice()
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> AsMut<NonEmptySlice<T>> for NonEmptyVec<T> {
#[inline]
fn as_mut(&mut self) -> &mut NonEmptySlice<T> {
self.as_mut_slice()
}
}
impl<T> AsRef<Vec<T>> for NonEmptyVec<T> {
#[inline]
fn as_ref(&self) -> &Vec<T> {
&self.inner
}
}
impl<T> Borrow<[T]> for NonEmptyVec<T> {
#[inline]
fn borrow(&self) -> &[T] {
self
}
}
impl<T> BorrowMut<[T]> for NonEmptyVec<T> {
#[inline]
fn borrow_mut(&mut self) -> &mut [T] {
self
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> Borrow<NonEmptySlice<T>> for NonEmptyVec<T> {
#[inline]
fn borrow(&self) -> &NonEmptySlice<T> {
self
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> BorrowMut<NonEmptySlice<T>> for NonEmptyVec<T> {
#[inline]
fn borrow_mut(&mut self) -> &mut NonEmptySlice<T> {
self
}
}
impl<T, I> ops::Index<I> for NonEmptyVec<T>
where
I: SliceIndex<[T]>,
{
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
ops::Index::index(&self.inner, index)
}
}
impl<T, I> ops::IndexMut<I> for NonEmptyVec<T>
where
I: SliceIndex<[T]>,
{
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
ops::IndexMut::index_mut(&mut self.inner, index)
}
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
impl<'a, T> Extend<&'a T> for NonEmptyVec<T>
where
T: 'a + Copy,
{
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.inner.extend(iter);
}
}
#[cfg(not(no_global_oom_handling))]
#[cfg_attr(doc_cfg, doc(cfg(not(no_global_oom_handling))))]
impl<T> Extend<T> for NonEmptyVec<T> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.inner.extend(iter);
}
}
impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
type Item = &'a T;
type IntoIter = slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
type Item = &'a mut T;
type IntoIter = slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T> IntoIterator for NonEmptyVec<T> {
type Item = T;
type IntoIter = vec::IntoIter<T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<T, U> PartialEq<VecDeque<U>> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &VecDeque<U>) -> bool {
if self.inner.len() != other.len() {
return false;
}
let (oa, ob) = other.as_slices();
let (sa, sb) = self.split_at(oa.len());
sa == oa && sb == ob
}
}
impl<T, U> PartialEq<NonEmptyVec<U>> for VecDeque<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self == &other.inner
}
}
impl<T, U> PartialEq<NonEmptyVec<U>> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self.inner == other.inner
}
}
impl<T, U> PartialEq<Vec<U>> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &Vec<U>) -> bool {
&self.inner == other
}
}
impl<T, U> PartialEq<NonEmptyVec<U>> for Vec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self == &other.inner
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T, U> PartialEq<NonEmptySlice<U>> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptySlice<U>) -> bool {
self.as_slice() == other
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T, U> PartialEq<NonEmptyVec<U>> for NonEmptySlice<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self == other.as_slice()
}
}
impl<T, U> PartialEq<[U]> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &[U]) -> bool {
self.inner == other
}
}
impl<T, U> PartialEq<NonEmptyVec<U>> for [T]
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self == other.inner
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for NonEmptyVec<T>
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &[U; N]) -> bool {
self.inner == other
}
}
impl<T, U, const N: usize> PartialEq<NonEmptyVec<U>> for [T; N]
where
T: PartialEq<U>,
{
#[inline]
fn eq(&self, other: &NonEmptyVec<U>) -> bool {
self == other.as_slice()
}
}
impl<T> Eq for NonEmptyVec<T> where T: Eq {}
impl<T> PartialOrd for NonEmptyVec<T>
where
T: PartialOrd,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
PartialOrd::partial_cmp(&self.inner, &other.inner)
}
}
impl<T> Ord for NonEmptyVec<T>
where
T: Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self.inner, &other.inner)
}
}
impl<T> Hash for NonEmptyVec<T>
where
T: Hash,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner.hash(state);
}
}
impl<T> From<NonEmptyVec<T>> for Arc<[T]> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
Arc::from(value.inner)
}
}
impl<T> From<NonEmptyVec<T>> for Box<[T]> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
value.inner.into_boxed_slice()
}
}
impl<'a, T> From<&'a NonEmptyVec<T>> for Cow<'a, [T]>
where
T: Clone,
{
#[inline]
fn from(v: &'a NonEmptyVec<T>) -> Self {
Cow::Borrowed(v)
}
}
impl<T> From<NonEmptyVec<T>> for Rc<[T]> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
Rc::from(value.inner)
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> From<NonEmptyVec<T>> for Arc<NonEmptySlice<T>> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
let arc: Arc<[T]> = Arc::from(value);
let ptr = Arc::into_raw(arc) as *const NonEmptySlice<T>;
unsafe { Arc::from_raw(ptr) }
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> From<NonEmptyVec<T>> for Box<NonEmptySlice<T>> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
value.into_boxed_slice()
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<'a, T> From<&'a NonEmptyVec<T>> for Cow<'a, NonEmptySlice<T>>
where
T: Clone,
{
#[inline]
fn from(v: &'a NonEmptyVec<T>) -> Self {
Cow::Borrowed(v)
}
}
#[cfg_attr(doc_cfg, doc(cfg(any(feature = "alloc", feature = "std"))))]
impl<T> From<NonEmptyVec<T>> for Rc<NonEmptySlice<T>> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
let rc: Rc<[T]> = Rc::from(value);
let ptr = Rc::into_raw(rc) as *const NonEmptySlice<T>;
unsafe { Rc::from_raw(ptr) }
}
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl From<NonEmptyVec<NonZeroU8>> for CString {
#[inline]
fn from(value: NonEmptyVec<NonZeroU8>) -> Self {
CString::from(value.inner)
}
}
impl<T> From<NonEmptyVec<T>> for Vec<T> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
value.inner
}
}
impl<T> From<NonEmptyVec<T>> for VecDeque<T> {
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
VecDeque::from(value.inner)
}
}
impl<T> From<NonEmptyVec<T>> for BinaryHeap<T>
where
T: Ord,
{
#[inline]
fn from(value: NonEmptyVec<T>) -> Self {
BinaryHeap::from(value.inner)
}
}
impl<T> TryFrom<&[T]> for NonEmptyVec<T>
where
T: Clone,
{
type Error = EmptyError;
#[inline]
fn try_from(value: &[T]) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl<T> TryFrom<&mut [T]> for NonEmptyVec<T>
where
T: Clone,
{
type Error = EmptyError;
#[inline]
fn try_from(value: &mut [T]) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl<'a, T> TryFrom<Cow<'a, [T]>> for NonEmptyVec<T>
where
[T]: ToOwned<Owned = Vec<T>>,
{
type Error = EmptyError;
fn try_from(value: Cow<'a, [T]>) -> Result<Self, Self::Error> {
let vec = value.into_owned();
NonEmptyVec::new(vec)
}
}
impl TryFrom<&str> for NonEmptyVec<u8> {
type Error = EmptyError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl TryFrom<String> for NonEmptyVec<u8> {
type Error = EmptyError;
#[inline]
fn try_from(value: String) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl TryFrom<CString> for NonEmptyVec<u8> {
type Error = EmptyError;
#[inline]
fn try_from(value: CString) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
type Error = EmptyError;
#[inline]
fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
NonEmptyVec::new(value)
}
}
impl<T> TryFrom<VecDeque<T>> for NonEmptyVec<T> {
type Error = EmptyError;
#[inline]
fn try_from(value: VecDeque<T>) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl<T> TryFrom<BinaryHeap<T>> for NonEmptyVec<T> {
type Error = EmptyError;
#[inline]
fn try_from(value: BinaryHeap<T>) -> Result<Self, Self::Error> {
NonEmptyVec::new(value.into())
}
}
impl<T, const N: usize> TryFrom<NonEmptyVec<T>> for [T; N] {
type Error = NonEmptyVec<T>;
fn try_from(mut value: NonEmptyVec<T>) -> Result<Self, Self::Error> {
if value.inner.len() != N {
return Err(value);
}
unsafe { value.inner.set_len(0) };
let array = unsafe { ptr::read(value.as_ptr().cast::<[T; N]>()) };
Ok(array)
}
}
#[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl Write for NonEmptyVec<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Write::write(&mut self.inner, buf)
}
#[inline]
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
Write::write_vectored(&mut self.inner, bufs)
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
Write::write_all(&mut self.inner, buf)
}
#[inline]
fn flush(&mut self) -> io::Result<()> {
Write::flush(&mut self.inner)
}
}
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl<T> serde::Serialize for NonEmptyVec<T>
where
T: serde::Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(&self.inner, serializer)
}
}
#[cfg(all(feature = "serde", not(no_global_oom_handling)))]
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "serde", not(no_global_oom_handling)))))]
impl<'de, T> serde::Deserialize<'de> for NonEmptyVec<T>
where
T: serde::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let vec: Vec<T> = serde::Deserialize::deserialize(deserializer)?;
NonEmptyVec::new(vec).map_err(|_| {
serde::de::Error::custom("cannot deserialize `NonEmptyVec` from an empty sequence")
})
}
}