Skip to main content

non_empty_slice/
boxed.rs

1//! Non-empty [`Box<[T]>`](Box).
2
3use core::mem::MaybeUninit;
4
5cfg_select! {
6    feature = "std" => {
7        use std::vec::IntoIter;
8    }
9    feature = "alloc" => {
10        use alloc::{
11            boxed::Box,
12            vec::{IntoIter, Vec},
13        };
14    }
15    _ => {
16        compile_error!("expected either `std` or `alloc` to be enabled");
17    }
18}
19
20use non_empty_iter::{FromNonEmptyIterator, IntoNonEmptyIterator};
21use non_zero_size::Size;
22use thiserror::Error;
23
24use crate::{
25    internals::debug_empty,
26    iter::IntoNonEmptyIter,
27    slice::{EmptySlice, NonEmptyMaybeUninitSlice, NonEmptySlice},
28    vec::{EmptyVec, NonEmptyVec},
29};
30
31/// Represents non-empty boxed slices, [`Box<NonEmptySlice<T>>`].
32pub type NonEmptyBoxedSlice<T> = Box<NonEmptySlice<T>>;
33
34/// Represents non-empty boxed slices of possibly uninitialized values,
35/// [`NonEmptyBoxedSlice<MaybeUninit<T>>`].
36pub type NonEmptyMaybeUninitBoxedSlice<T> = NonEmptyBoxedSlice<MaybeUninit<T>>;
37
38/// Represents non-empty boxed bytes, [`NonEmptyBoxedSlice<u8>`].
39pub type NonEmptyBoxedBytes = NonEmptyBoxedSlice<u8>;
40
41/// The error message used when the boxed slice is empty.
42pub const EMPTY_BOXED_SLICE: &str = "the boxed slice is empty";
43
44/// Similar to [`EmptyVec<T>`], but contains the empty boxed slice provided.
45#[derive(Error)]
46#[error("{EMPTY_BOXED_SLICE}")]
47pub struct EmptyBoxedSlice<T> {
48    boxed: Box<[T]>,
49}
50
51debug_empty!(EmptyBoxedSlice, boxed);
52
53/// Represents empty boxed bytes, [`EmptyBoxedSlice<u8>`].
54pub type EmptyBoxedBytes = EmptyBoxedSlice<u8>;
55
56impl<T> EmptyBoxedSlice<T> {
57    pub(crate) const fn new(boxed: Box<[T]>) -> Self {
58        Self { boxed }
59    }
60
61    /// Returns the contained empty boxed slice.
62    #[must_use]
63    pub fn get(self) -> Box<[T]> {
64        self.boxed
65    }
66
67    /// Constructs [`Self`] from [`EmptyVec<T>`].
68    #[must_use]
69    pub fn from_empty_vec(empty: EmptyVec<T>) -> Self {
70        Self::new(empty.get().into_boxed_slice())
71    }
72
73    /// Converts [`Self`] into [`EmptyVec<T>`].
74    #[must_use]
75    pub fn into_empty_vec(self) -> EmptyVec<T> {
76        EmptyVec::from_empty_boxed_slice(self)
77    }
78}
79
80impl<T> From<NonEmptyBoxedSlice<T>> for Box<[T]> {
81    fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
82        boxed.into_boxed_slice()
83    }
84}
85
86impl<T> TryFrom<Box<[T]>> for NonEmptyBoxedSlice<T> {
87    type Error = EmptyBoxedSlice<T>;
88
89    fn try_from(boxed: Box<[T]>) -> Result<Self, Self::Error> {
90        NonEmptySlice::from_boxed_slice(boxed)
91    }
92}
93
94impl<T> TryFrom<Vec<T>> for NonEmptyBoxedSlice<T> {
95    type Error = EmptyVec<T>;
96
97    fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
98        let non_empty_vec = NonEmptyVec::new(vec)?;
99
100        Ok(non_empty_vec.into())
101    }
102}
103
104impl<T> From<NonEmptyBoxedSlice<T>> for Vec<T> {
105    fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
106        boxed.into_boxed_slice().into_vec()
107    }
108}
109
110impl<T> From<NonEmptyBoxedSlice<T>> for NonEmptyVec<T> {
111    fn from(boxed: NonEmptyBoxedSlice<T>) -> Self {
112        boxed.into_non_empty_vec()
113    }
114}
115
116impl<T> From<NonEmptyVec<T>> for NonEmptyBoxedSlice<T> {
117    fn from(non_empty: NonEmptyVec<T>) -> Self {
118        non_empty.into_non_empty_boxed_slice()
119    }
120}
121
122impl<T: Clone> TryFrom<&[T]> for NonEmptyBoxedSlice<T> {
123    type Error = EmptySlice;
124
125    fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
126        let non_empty_slice = NonEmptySlice::try_from_slice(slice)?;
127
128        Ok(non_empty_slice.into())
129    }
130}
131
132impl<T: Clone> TryFrom<&mut [T]> for NonEmptyBoxedSlice<T> {
133    type Error = EmptySlice;
134
135    fn try_from(slice: &mut [T]) -> Result<Self, Self::Error> {
136        let non_empty_slice = NonEmptySlice::try_from_mut_slice(slice)?;
137
138        Ok(non_empty_slice.into())
139    }
140}
141
142impl<T: Clone> From<&NonEmptySlice<T>> for NonEmptyBoxedSlice<T> {
143    fn from(non_empty: &NonEmptySlice<T>) -> Self {
144        non_empty.to_non_empty_vec().into_non_empty_boxed_slice()
145    }
146}
147
148impl<T: Clone> From<&mut NonEmptySlice<T>> for NonEmptyBoxedSlice<T> {
149    fn from(non_empty: &mut NonEmptySlice<T>) -> Self {
150        non_empty.to_non_empty_vec().into_non_empty_boxed_slice()
151    }
152}
153
154impl<T: Clone> Clone for NonEmptyBoxedSlice<T> {
155    fn clone(&self) -> Self {
156        self.to_non_empty_vec().into_non_empty_boxed_slice()
157    }
158
159    fn clone_from(&mut self, source: &Self) {
160        if self.len() == source.len() {
161            self.clone_from_non_empty_slice(source);
162        } else {
163            *self = source.clone();
164        }
165    }
166}
167
168impl<T> NonEmptySlice<T> {
169    /// Constructs [`Self`] from [`Box<[T]>`](Box), provided the boxed slice is non-empty.
170    ///
171    /// # Errors
172    ///
173    /// Returns [`EmptyBoxedSlice<T>`] if the boxed slice is empty.
174    pub fn from_boxed_slice(boxed: Box<[T]>) -> Result<Box<Self>, EmptyBoxedSlice<T>> {
175        if boxed.is_empty() {
176            return Err(EmptyBoxedSlice::new(boxed));
177        }
178
179        // SAFETY: the boxed slice is non-empty at this point
180        Ok(unsafe { Self::from_boxed_slice_unchecked(boxed) })
181    }
182
183    /// Constructs [`Self`] from [`Box<[T]>`](Box), without checking if the boxed slice is empty.
184    ///
185    /// # Safety
186    ///
187    /// The caller must ensure that the boxed slice is non-empty.
188    #[must_use]
189    pub unsafe fn from_boxed_slice_unchecked(boxed: Box<[T]>) -> Box<Self> {
190        // SAFETY: the caller must ensure that the boxed slice is non-empty
191        // moreover, `Self` is `repr(transparent)`, so it is safe to transmute
192        // finally, `Box` is created from the raw pointer existing within this function only
193        unsafe { Box::from_raw(Box::into_raw(boxed) as *mut Self) }
194    }
195
196    /// Converts [`Self`] into [`Box<[T]>`](Box).
197    #[must_use]
198    pub fn into_boxed_slice(self: Box<Self>) -> Box<[T]> {
199        // SAFETY: `Self` is `repr(transparent)`, so it is safe to transmute
200        // moreover, `Box` is created from the raw pointer existing within this function only
201        unsafe { Box::from_raw(Box::into_raw(self) as *mut [T]) }
202    }
203
204    /// Constructs [`Self`] from [`NonEmptyVec<T>`].
205    #[must_use]
206    pub fn from_non_empty_vec(non_empty: NonEmptyVec<T>) -> Box<Self> {
207        // SAFETY: the vector is non-empty by construction, so is the underlying boxed slice
208        unsafe { Self::from_boxed_slice_unchecked(non_empty.into_vec().into_boxed_slice()) }
209    }
210
211    /// Converts [`Self`] into [`NonEmptyVec<T>`].
212    #[must_use]
213    pub fn into_non_empty_vec(self: Box<Self>) -> NonEmptyVec<T> {
214        NonEmptyVec::from_non_empty_boxed_slice(self)
215    }
216
217    /// Constructs uninitialized [`NonEmptyMaybeUninitBoxedSlice<T>`] of given non-zero length.
218    #[must_use]
219    pub fn new_uninit(len: Size) -> NonEmptyMaybeUninitBoxedSlice<T> {
220        let boxed = Box::new_uninit_slice(len.get());
221
222        // SAFETY: `len` is non-zero, therefore this is safe
223        unsafe { NonEmptySlice::from_boxed_slice_unchecked(boxed) }
224    }
225}
226
227impl<T> FromNonEmptyIterator<T> for NonEmptyBoxedSlice<T> {
228    fn from_non_empty_iter<I: IntoNonEmptyIterator<Item = T>>(iterable: I) -> Self {
229        let non_empty_vec = NonEmptyVec::from_non_empty_iter(iterable);
230
231        non_empty_vec.into_non_empty_boxed_slice()
232    }
233}
234
235impl<T> NonEmptyMaybeUninitSlice<T> {
236    /// Converts [`Self`] into initialized [`NonEmptyBoxedSlice<T>`].
237    ///
238    /// # Safety
239    ///
240    /// The caller must guarantee that the items are in initialized state.
241    /// Calling this when the contents are not fully initialized causes
242    /// *immediate undefined behavior*.
243    #[must_use]
244    pub unsafe fn assume_init(self: Box<Self>) -> NonEmptyBoxedSlice<T> {
245        // SAFETY: the caller must guarantee that the items are in initialized state
246        let boxed = unsafe { self.into_boxed_slice().assume_init() };
247
248        // SAFETY: `self` is non-empty, so is `boxed`, therefore this is safe
249        unsafe { NonEmptySlice::from_boxed_slice_unchecked(boxed) }
250    }
251}
252
253impl<T> NonEmptyVec<T> {
254    /// Constructs [`Self`] from [`NonEmptyBoxedSlice<T>`].
255    #[must_use]
256    pub fn from_non_empty_boxed_slice(non_empty: NonEmptyBoxedSlice<T>) -> Self {
257        // SAFETY: the boxed slice is non-empty by construction
258        unsafe { Self::new_unchecked(non_empty.into_boxed_slice().into_vec()) }
259    }
260
261    /// Converts [`Self`] into [`NonEmptyBoxedSlice<T>`].
262    #[must_use]
263    pub fn into_non_empty_boxed_slice(self) -> NonEmptyBoxedSlice<T> {
264        NonEmptySlice::from_non_empty_vec(self)
265    }
266
267    /// Converts [`Self`] into [`Box<[T]>`](Box).
268    #[must_use]
269    pub fn into_boxed_slice(self) -> Box<[T]> {
270        self.into_non_empty_boxed_slice().into_boxed_slice()
271    }
272}
273
274impl<T> IntoIterator for NonEmptyBoxedSlice<T> {
275    type Item = T;
276
277    type IntoIter = IntoIter<T>;
278
279    fn into_iter(self) -> Self::IntoIter {
280        self.into_non_empty_vec().into_iter()
281    }
282}
283
284impl<T> IntoNonEmptyIterator for NonEmptyBoxedSlice<T> {
285    type IntoNonEmptyIter = IntoNonEmptyIter<T>;
286
287    fn into_non_empty_iter(self) -> Self::IntoNonEmptyIter {
288        self.into_non_empty_vec().into_non_empty_iter()
289    }
290}