1#[cfg(feature = "alloc")]
2use alloc::{boxed::Box, vec};
3use core::iter::FromIterator;
4use core::mem::transmute;
5
6#[cfg(all(feature = "alloc", feature = "serde"))]
7use serde::de::{Deserialize, Deserializer};
8
9use crate::{TiSlice, TiVec};
10
11impl<K, V> From<Box<TiSlice<K, V>>> for Box<[V]> {
12 #[inline]
13 fn from(slice: Box<TiSlice<K, V>>) -> Self {
14 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
15 unsafe { transmute::<Box<TiSlice<K, V>>, Self>(src:slice) }
16 }
17}
18
19impl<K, V> From<Box<[V]>> for Box<TiSlice<K, V>> {
20 #[inline]
21 fn from(slice: Box<[V]>) -> Self {
22 // SAFETY: `TiSlice<K, V>` is `repr(transparent)` over a `[V]` type.
23 unsafe { transmute::<Box<[V]>, Self>(src:slice) }
24 }
25}
26
27impl<K, V: Clone> Clone for Box<TiSlice<K, V>> {
28 #[inline]
29 fn clone(&self) -> Self {
30 self.to_vec().into_boxed_slice()
31 }
32}
33
34impl<K, V> IntoIterator for Box<TiSlice<K, V>> {
35 type Item = V;
36 type IntoIter = vec::IntoIter<V>;
37
38 #[inline]
39 fn into_iter(self) -> Self::IntoIter {
40 self.into_vec().into_iter()
41 }
42}
43
44impl<K, V> Default for Box<TiSlice<K, V>> {
45 #[inline]
46 fn default() -> Self {
47 TiVec::new().into()
48 }
49}
50
51impl<K, V: Copy> From<&TiSlice<K, V>> for Box<TiSlice<K, V>> {
52 #[inline]
53 fn from(slice: &TiSlice<K, V>) -> Self {
54 Box::<[V]>::from(&slice.raw).into()
55 }
56}
57
58impl<K, V> From<Box<TiSlice<K, V>>> for TiVec<K, V> {
59 #[inline]
60 fn from(s: Box<TiSlice<K, V>>) -> Self {
61 s.into_vec()
62 }
63}
64
65impl<K, V> From<TiVec<K, V>> for Box<TiSlice<K, V>> {
66 #[inline]
67 fn from(v: TiVec<K, V>) -> Self {
68 v.into_boxed_slice()
69 }
70}
71
72impl<K, V> FromIterator<V> for Box<TiSlice<K, V>> {
73 #[inline]
74 fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
75 iter.into_iter().collect::<TiVec<K, V>>().into_boxed_slice()
76 }
77}
78
79#[cfg(all(feature = "alloc", feature = "serde"))]
80#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "serde"))))]
81impl<'de, K, V: Deserialize<'de>> Deserialize<'de> for Box<TiSlice<K, V>> {
82 #[inline]
83 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
84 Box::<[V]>::deserialize(deserializer).map(Into::into)
85 }
86}
87
88#[expect(dead_code, unused_imports, unused_mut, reason = "okay in tests")]
89#[cfg(test)]
90mod test {
91 use alloc::borrow::{Cow, ToOwned};
92 use alloc::boxed::Box;
93 use alloc::ffi::CString;
94 use alloc::string::ToString;
95 use alloc::vec::Vec;
96 use core::borrow::{Borrow, BorrowMut};
97 use core::hash::{Hash, Hasher};
98 use core::ops::Bound;
99 #[cfg(feature = "std")]
100 use std::hash::DefaultHasher;
101 #[cfg(feature = "std")]
102 use std::io::{IoSlice, Write};
103
104 use crate::test_util::{AsSliceAndCapacity, Id};
105 use crate::{TiSlice, TiVec};
106
107 #[test]
108 fn test_boxed_slice_api_compatibility() {
109 for v in [
110 &[0_u32; 0][..],
111 &[1],
112 &[1, 1234],
113 &[1, 2, 4],
114 &[1, 5, 3, 2],
115 &[1, 1, 9, 2, 4, 1, 12345, 12],
116 ] {
117 let mut cv = (v, TiSlice::from_ref(v));
118 assert_eq_api!(
119 cv, v => Box::<TheSlice<u32>>::from(v) == <Box<TheSlice<u32>>>::default()
120 );
121 assert_eq_api!(cv, v => Box::<TheSlice<_>>::from(v).into_std());
122 assert_eq_api!(cv, v => Box::<TheSlice<_>>::from(v).clone().into_std());
123 assert_eq_api!(
124 cv, v => IntoIterator::into_iter(Box::<TheSlice<u32>>::from(v)).collect::<Vec<_>>()
125 );
126 assert_eq_api!(cv, v => TheVec::from(Box::<TheSlice<_>>::from(v)).into_std());
127 assert_eq_api!(cv, v => Box::<TheSlice<_>>::from(TheVec::from(v)).into_std());
128 assert_eq_api!(cv, v => v.iter().copied().collect::<Box<TheSlice<_>>>().into_std());
129 }
130 }
131
132 #[expect(clippy::unwrap_used, reason = "okay in tests")]
133 #[cfg(feature = "serde")]
134 #[test]
135 fn test_boxed_slice_deserialize() {
136 let s0: Box<TiSlice<Id, u32>> = serde_json::from_str("[]").unwrap();
137 let s1: Box<TiSlice<Id, u32>> = serde_json::from_str("[12]").unwrap();
138 let s2: Box<TiSlice<Id, u32>> = serde_json::from_str("[23, 34]").unwrap();
139 assert_eq!(s0.as_ref().raw, [0; 0][..]);
140 assert_eq!(s1.as_ref().raw, [12][..]);
141 assert_eq!(s2.as_ref().raw, [23, 34][..]);
142 }
143}
144