non_empty_slice/
boxed.rs

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