1#[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
28pub type NonEmptyBoxedSlice<T> = Box<NonEmptySlice<T>>;
30
31pub type NonEmptyMaybeUninitBoxedSlice<T> = NonEmptyBoxedSlice<MaybeUninit<T>>;
34
35pub type NonEmptyBoxedBytes = NonEmptyBoxedSlice<u8>;
37
38pub const EMPTY_BOXED_SLICE: &str = "the boxed slice is empty";
40
41#[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
58pub 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 #[must_use]
68 pub fn get(self) -> Box<[T]> {
69 self.boxed
70 }
71
72 #[must_use]
74 pub fn from_empty_vec(empty: EmptyVec<T>) -> Self {
75 Self::new(empty.get().into_boxed_slice())
76 }
77
78 #[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 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 Ok(unsafe { Self::from_boxed_slice_unchecked(boxed) })
186 }
187
188 #[must_use]
194 pub unsafe fn from_boxed_slice_unchecked(boxed: Box<[T]>) -> Box<Self> {
195 unsafe { Box::from_raw(Box::into_raw(boxed) as *mut Self) }
199 }
200
201 #[must_use]
203 pub fn into_boxed_slice(self: Box<Self>) -> Box<[T]> {
204 unsafe { Box::from_raw(Box::into_raw(self) as *mut [T]) }
207 }
208
209 #[must_use]
211 pub fn from_non_empty_vec(non_empty: NonEmptyVec<T>) -> Box<Self> {
212 unsafe { Self::from_boxed_slice_unchecked(non_empty.into_vec().into_boxed_slice()) }
214 }
215
216 #[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 #[must_use]
224 pub fn new_uninit(len: Size) -> NonEmptyMaybeUninitBoxedSlice<T> {
225 let boxed = Box::new_uninit_slice(len.get());
226
227 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 #[must_use]
249 pub unsafe fn assume_init(self: Box<Self>) -> NonEmptyBoxedSlice<T> {
250 let boxed = unsafe { self.into_boxed_slice().assume_init() };
252
253 unsafe { NonEmptySlice::from_boxed_slice_unchecked(boxed) }
255 }
256}
257
258impl<T> NonEmptyVec<T> {
259 #[must_use]
261 pub fn from_non_empty_boxed_slice(non_empty: NonEmptyBoxedSlice<T>) -> Self {
262 unsafe { Self::new_unchecked(non_empty.into_boxed_slice().into_vec()) }
264 }
265
266 #[must_use]
268 pub fn into_non_empty_boxed_slice(self) -> NonEmptyBoxedSlice<T> {
269 NonEmptySlice::from_non_empty_vec(self)
270 }
271
272 #[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}