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 Single([T; 1]),
18}
19
20impl<T: fmt::Debug + ImplicitClone + 'static> fmt::Debug for IArray<T> {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 match self {
24 Self::Static(a) => a.fmt(f),
25 Self::Rc(a) => a.fmt(f),
26 Self::Single(x) => x.fmt(f),
27 }
28 }
29}
30
31impl<T: ImplicitClone + 'static> Clone for IArray<T> {
32 fn clone(&self) -> Self {
33 match self {
34 Self::Static(a) => Self::Static(a),
35 Self::Rc(a) => Self::Rc(a.clone()),
36 Self::Single(x) => Self::Single(x.clone()),
37 }
38 }
39}
40
41impl<T: ImplicitClone + 'static> Default for IArray<T> {
42 fn default() -> Self {
43 Self::EMPTY
44 }
45}
46
47impl<T: ImplicitClone + 'static> FromIterator<T> for IArray<T> {
48 fn from_iter<I: IntoIterator<Item = T>>(it: I) -> Self {
49 let mut it = it.into_iter();
50 match it.size_hint() {
51 (_, Some(0)) => Self::EMPTY,
52 (_, Some(1)) => {
53 if let Some(element) = it.next() {
54 Self::Single([element])
55 } else {
56 Self::EMPTY
57 }
58 }
59 _ => Self::Rc(Rc::from_iter(it)),
60 }
61 }
62}
63
64impl<T: ImplicitClone + 'static> ImplicitClone for IArray<T> {}
65
66impl<T: ImplicitClone + 'static> From<&'static [T]> for IArray<T> {
67 fn from(a: &'static [T]) -> IArray<T> {
68 IArray::Static(a)
69 }
70}
71
72impl<T: ImplicitClone + 'static> From<Vec<T>> for IArray<T> {
73 fn from(a: Vec<T>) -> IArray<T> {
74 IArray::Rc(Rc::from(a))
75 }
76}
77
78impl<T: ImplicitClone + 'static> From<Rc<[T]>> for IArray<T> {
79 fn from(a: Rc<[T]>) -> IArray<T> {
80 IArray::Rc(a)
81 }
82}
83
84impl<T: ImplicitClone + 'static> From<&IArray<T>> for IArray<T> {
85 fn from(a: &IArray<T>) -> IArray<T> {
86 a.clone()
87 }
88}
89
90impl<T: ImplicitClone + 'static> From<[T; 1]> for IArray<T> {
91 fn from(a: [T; 1]) -> IArray<T> {
92 IArray::Single(a)
93 }
94}
95
96#[derive(Debug)]
98pub struct Iter<T: ImplicitClone + 'static> {
99 array: IArray<T>,
100 left: usize,
101 right: usize,
102}
103
104impl<T: ImplicitClone + 'static> Iter<T> {
105 fn new(array: IArray<T>) -> Self {
106 Self {
107 left: 0,
108 right: array.len(),
109 array,
110 }
111 }
112}
113
114impl<T: ImplicitClone + 'static> Iterator for Iter<T> {
115 type Item = T;
116
117 fn next(&mut self) -> Option<Self::Item> {
118 if self.left >= self.right {
119 return None;
120 }
121 let item = self.array.get(self.left);
122 self.left += 1;
123 item
124 }
125}
126
127impl<T: ImplicitClone + 'static> DoubleEndedIterator for Iter<T> {
128 fn next_back(&mut self) -> Option<Self::Item> {
129 if self.left >= self.right {
130 return None;
131 }
132 self.right -= 1;
133 self.array.get(self.right)
134 }
135}
136
137impl<T: ImplicitClone + 'static> IArray<T> {
138 pub const EMPTY: Self = Self::Static(&[]);
140
141 #[inline]
160 pub fn iter(&self) -> Iter<T> {
161 Iter::new(self.clone())
162 }
163
164 #[inline]
175 pub fn len(&self) -> usize {
176 match self {
177 Self::Static(a) => a.len(),
178 Self::Rc(a) => a.len(),
179 Self::Single(_) => 1,
180 }
181 }
182
183 #[inline]
196 pub fn is_empty(&self) -> bool {
197 match self {
198 Self::Static(a) => a.is_empty(),
199 Self::Rc(a) => a.is_empty(),
200 Self::Single(_) => false,
201 }
202 }
203
204 #[inline]
217 pub fn as_slice(&self) -> &[T] {
218 match self {
219 Self::Static(a) => a,
220 Self::Rc(a) => a,
221 Self::Single(a) => a,
222 }
223 }
224
225 #[inline]
236 pub fn get(&self, index: usize) -> Option<T> {
237 match self {
238 Self::Static(a) => a.get(index).cloned(),
239 Self::Rc(a) => a.get(index).cloned(),
240 Self::Single(a) if index == 0 => Some(a[0].clone()),
241 Self::Single(_) => None,
242 }
243 }
244
245 #[inline]
274 pub fn get_mut(&mut self) -> Option<&mut [T]> {
275 match self {
276 Self::Rc(ref mut rc) => Rc::get_mut(rc),
277 Self::Static(_) => None,
278 Self::Single(ref mut a) => Some(a),
279 }
280 }
281
282 #[inline]
340 pub fn make_mut(&mut self) -> &mut [T] {
341 match self {
342 Self::Rc(ref mut rc) => {
343 if Rc::get_mut(rc).is_none() {
348 *rc = rc.iter().cloned().collect::<Rc<[T]>>();
349 }
350 Rc::get_mut(rc).unwrap()
351 }
352 Self::Static(slice) => {
353 *self = Self::Rc(slice.iter().cloned().collect());
354 match self {
355 Self::Rc(rc) => Rc::get_mut(rc).unwrap(),
356 _ => unreachable!(),
357 }
358 }
359 Self::Single(array) => array,
360 }
361 }
362}
363
364impl<'a, T, U, const N: usize> PartialEq<&'a [U; N]> for IArray<T>
365where
366 T: PartialEq<U> + ImplicitClone,
367{
368 fn eq(&self, other: &&[U; N]) -> bool {
369 match self {
370 Self::Static(a) => a.eq(other),
371 Self::Rc(a) => a.eq(*other),
372 Self::Single(a) if N == 1 => a[0].eq(&other[0]),
373 Self::Single(_) => false,
374 }
375 }
376}
377
378impl<T, U, const N: usize> PartialEq<[U; N]> for IArray<T>
379where
380 T: PartialEq<U> + ImplicitClone,
381{
382 fn eq(&self, other: &[U; N]) -> bool {
383 match self {
384 Self::Static(a) => a.eq(other),
385 Self::Rc(a) => a.eq(other),
386 Self::Single(a) if N == 1 => a[0].eq(&other[0]),
387 Self::Single(_) => false,
388 }
389 }
390}
391
392impl<T, U> PartialEq<[U]> for IArray<T>
393where
394 T: PartialEq<U> + ImplicitClone,
395{
396 fn eq(&self, other: &[U]) -> bool {
397 match self {
398 Self::Static(a) => a.eq(&other),
399 Self::Rc(a) => a.eq(other),
400 Self::Single(a) => a.eq(other),
401 }
402 }
403}
404
405impl<'a, T, U> PartialEq<&'a [U]> for IArray<T>
406where
407 T: PartialEq<U> + ImplicitClone,
408{
409 fn eq(&self, other: &&[U]) -> bool {
410 match self {
411 Self::Static(a) => a.eq(other),
412 Self::Rc(a) => a.eq(*other),
413 Self::Single(a) => a.eq(*other),
414 }
415 }
416}
417
418impl<T> std::ops::Deref for IArray<T>
419where
420 T: ImplicitClone,
421{
422 type Target = [T];
423
424 fn deref(&self) -> &Self::Target {
425 self.as_slice()
426 }
427}
428
429#[cfg(feature = "serde")]
430impl<T: serde::Serialize + ImplicitClone> serde::Serialize for IArray<T> {
431 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
432 <[T] as serde::Serialize>::serialize(self, serializer)
433 }
434}
435
436#[cfg(feature = "serde")]
437impl<'de, T: serde::Deserialize<'de> + ImplicitClone> serde::Deserialize<'de> for IArray<T> {
438 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
439 <Vec<T> as serde::Deserialize>::deserialize(deserializer).map(IArray::<T>::from)
440 }
441}
442
443#[cfg(test)]
444mod test_array {
445 use super::*;
446
447 #[test]
448 fn array_in_array() {
449 let array_1 = [1, 2, 3].into_iter().collect::<IArray<u32>>();
450 let array_2 = [4, 5, 6].into_iter().collect::<IArray<u32>>();
451 let array_of_array = [array_1, array_2]
452 .into_iter()
453 .collect::<IArray<IArray<u32>>>();
454 assert_eq!(array_of_array, [[1, 2, 3], [4, 5, 6]]);
455 }
456
457 #[test]
458 fn array_holding_rc_items() {
459 struct Item;
460 let _array = [Rc::new(Item)].into_iter().collect::<IArray<Rc<Item>>>();
461 }
462
463 #[test]
464 fn from_iter_is_optimized() {
465 let array_0 = [].into_iter().collect::<IArray<u32>>();
466 assert!(matches!(array_0, IArray::Static(_)));
467 let array_1 = [1].into_iter().collect::<IArray<u32>>();
468 assert!(matches!(array_1, IArray::Single(_)));
469 let array_2 = [1, 2].into_iter().collect::<IArray<u32>>();
470 assert!(matches!(array_2, IArray::Rc(_)));
471 {
472 let it = [1].into_iter().filter(|x| x % 2 == 0);
473 assert_eq!(it.size_hint(), (0, Some(1)));
474 let array_0_to_1 = it.collect::<IArray<u32>>();
475 assert!(matches!(array_0_to_1, IArray::Static(_)));
476 }
477 {
478 let it = [2].into_iter().filter(|x| x % 2 == 0);
479 assert_eq!(it.size_hint(), (0, Some(1)));
480 let array_0_to_1 = it.collect::<IArray<u32>>();
481 assert!(matches!(array_0_to_1, IArray::Single(_)));
482 }
483 }
484
485 #[test]
486 fn static_array() {
487 const _ARRAY: IArray<u32> = IArray::Static(&[1, 2, 3]);
488 }
489
490 #[test]
491 fn deref_slice() {
492 assert!(IArray::Static(&[1, 2, 3]).contains(&1));
493 }
494
495 #[test]
496 fn tuple_in_array() {
497 const _ARRAY_2: IArray<(u32, u32)> = IArray::EMPTY;
498 const _ARRAY_5: IArray<(u32, u32, u32, u32, u32)> = IArray::EMPTY;
499 }
500
501 #[test]
502 fn floats_in_array() {
503 const _ARRAY_F32: IArray<f32> = IArray::EMPTY;
504 const _ARRAY_F64: IArray<f64> = IArray::EMPTY;
505 }
506
507 #[test]
508 fn from() {
509 let x: IArray<u32> = IArray::EMPTY;
510 let _out = IArray::from(&x);
511
512 let _array: IArray<u32> = IArray::from(&[1, 2, 3][..]);
513 let _array: IArray<u32> = IArray::from(vec![1, 2, 3]);
514 let _array: IArray<u32> = IArray::from(Rc::from(vec![1, 2, 3]));
515 let _array: IArray<u32> = IArray::from([1]);
516 }
517}