1use std::fmt;
2
3use super::Rc;
4use crate::ImplicitClone;
5
6#[derive(PartialEq, Eq)]
11pub enum IArray<T: ImplicitClone + 'static> {
12 Static(&'static [T]),
14 Rc(Rc<[T]>),
16}
17
18impl<T: fmt::Debug + ImplicitClone + 'static> fmt::Debug for IArray<T> {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 match self {
22 Self::Static(a) => a.fmt(f),
23 Self::Rc(a) => a.fmt(f),
24 }
25 }
26}
27
28impl<T: ImplicitClone + 'static> Clone for IArray<T> {
29 fn clone(&self) -> Self {
30 match self {
31 Self::Static(a) => Self::Static(a),
32 Self::Rc(a) => Self::Rc(a.clone()),
33 }
34 }
35}
36
37impl<T: ImplicitClone + 'static> Default for IArray<T> {
38 fn default() -> Self {
39 Self::Static(&[])
40 }
41}
42
43impl<T: ImplicitClone + 'static> FromIterator<T> for IArray<T> {
44 fn from_iter<I: IntoIterator<Item = T>>(it: I) -> Self {
45 let vec = it.into_iter().collect::<Vec<T>>();
46 Self::Rc(Rc::from(vec))
47 }
48}
49
50impl<T: ImplicitClone + 'static> ImplicitClone for IArray<T> {}
51
52impl<T: ImplicitClone + 'static> From<&'static [T]> for IArray<T> {
53 fn from(a: &'static [T]) -> IArray<T> {
54 IArray::Static(a)
55 }
56}
57
58impl<T: ImplicitClone + 'static> From<Vec<T>> for IArray<T> {
59 fn from(a: Vec<T>) -> IArray<T> {
60 IArray::Rc(Rc::from(a))
61 }
62}
63
64impl<T: ImplicitClone + 'static> From<Rc<[T]>> for IArray<T> {
65 fn from(a: Rc<[T]>) -> IArray<T> {
66 IArray::Rc(a)
67 }
68}
69
70impl<T: ImplicitClone + 'static> From<&IArray<T>> for IArray<T> {
71 fn from(a: &IArray<T>) -> IArray<T> {
72 a.clone()
73 }
74}
75
76impl<T: ImplicitClone + 'static> IArray<T> {
77 #[inline]
96 pub fn iter(&self) -> impl DoubleEndedIterator<Item = T> + '_ {
97 match self {
98 Self::Static(a) => a.iter().cloned(),
99 Self::Rc(a) => a.iter().cloned(),
100 }
101 }
102
103 #[inline]
114 pub fn len(&self) -> usize {
115 match self {
116 Self::Static(a) => a.len(),
117 Self::Rc(a) => a.len(),
118 }
119 }
120
121 #[inline]
134 pub fn is_empty(&self) -> bool {
135 match self {
136 Self::Static(a) => a.is_empty(),
137 Self::Rc(a) => a.is_empty(),
138 }
139 }
140
141 #[inline]
154 pub fn as_slice(&self) -> &[T] {
155 match self {
156 Self::Static(a) => a,
157 Self::Rc(a) => a,
158 }
159 }
160
161 #[inline]
172 pub fn get(&self, index: usize) -> Option<T> {
173 match self {
174 Self::Static(a) => a.get(index).cloned(),
175 Self::Rc(a) => a.get(index).cloned(),
176 }
177 }
178}
179
180impl<'a, T, U, const N: usize> PartialEq<&'a [U; N]> for IArray<T>
181where
182 T: PartialEq<U> + ImplicitClone,
183{
184 fn eq(&self, other: &&[U; N]) -> bool {
185 match self {
186 Self::Static(a) => a.eq(other),
187 Self::Rc(a) => a.eq(*other),
188 }
189 }
190}
191
192impl<T, U, const N: usize> PartialEq<[U; N]> for IArray<T>
193where
194 T: PartialEq<U> + ImplicitClone,
195{
196 fn eq(&self, other: &[U; N]) -> bool {
197 match self {
198 Self::Static(a) => a.eq(other),
199 Self::Rc(a) => a.eq(other),
200 }
201 }
202}
203
204impl<T, U> PartialEq<[U]> for IArray<T>
205where
206 T: PartialEq<U> + ImplicitClone,
207{
208 fn eq(&self, other: &[U]) -> bool {
209 match self {
210 Self::Static(a) => a.eq(&other),
211 Self::Rc(a) => a.eq(other),
212 }
213 }
214}
215
216impl<'a, T, U> PartialEq<&'a [U]> for IArray<T>
217where
218 T: PartialEq<U> + ImplicitClone,
219{
220 fn eq(&self, other: &&[U]) -> bool {
221 match self {
222 Self::Static(a) => a.eq(other),
223 Self::Rc(a) => a.eq(*other),
224 }
225 }
226}
227
228impl<T> std::ops::Deref for IArray<T>
229where
230 T: ImplicitClone,
231{
232 type Target = [T];
233
234 fn deref(&self) -> &Self::Target {
235 self.as_slice()
236 }
237}
238
239#[cfg(feature = "serde")]
240impl<T: serde::Serialize + ImplicitClone> serde::Serialize for IArray<T> {
241 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
242 <[T] as serde::Serialize>::serialize(self, serializer)
243 }
244}
245
246#[cfg(feature = "serde")]
247impl<'de, T: serde::Deserialize<'de> + ImplicitClone> serde::Deserialize<'de> for IArray<T> {
248 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
249 <Vec<T> as serde::Deserialize>::deserialize(deserializer).map(IArray::<T>::from)
250 }
251}
252
253#[cfg(test)]
254mod test_array {
255 use super::*;
256
257 #[test]
258 fn array_in_array() {
259 let array_1 = [1, 2, 3].into_iter().collect::<IArray<u32>>();
260 let array_2 = [4, 5, 6].into_iter().collect::<IArray<u32>>();
261 let array_of_array = [array_1, array_2]
262 .into_iter()
263 .collect::<IArray<IArray<u32>>>();
264 assert_eq!(array_of_array, [[1, 2, 3], [4, 5, 6]]);
265 }
266
267 #[test]
268 fn array_holding_rc_items() {
269 struct Item;
270 let _array = [Rc::new(Item)].into_iter().collect::<IArray<Rc<Item>>>();
271 }
272
273 #[test]
274 fn static_array() {
275 const _ARRAY: IArray<u32> = IArray::Static(&[1, 2, 3]);
276 }
277
278 #[test]
279 fn deref_slice() {
280 assert!(IArray::Static(&[1, 2, 3]).contains(&1));
281 }
282
283 #[test]
284 fn tuple_in_array() {
285 const _ARRAY_2: IArray<(u32, u32)> = IArray::Static(&[]);
286 const _ARRAY_5: IArray<(u32, u32, u32, u32, u32)> = IArray::Static(&[]);
287 }
288
289 #[test]
290 fn floats_in_array() {
291 const _ARRAY_F32: IArray<f32> = IArray::Static(&[]);
292 const _ARRAY_F64: IArray<f64> = IArray::Static(&[]);
293 }
294
295 #[test]
296 fn from() {
297 let x: IArray<u32> = IArray::Static(&[]);
298 let _out = IArray::from(&x);
299 }
300}