uiua/
array.rs

1use std::{
2    any::TypeId,
3    cmp::Ordering,
4    fmt,
5    hash::{Hash, Hasher},
6    ops::{Deref, DerefMut},
7    slice,
8    sync::Arc,
9};
10
11use bitflags::bitflags;
12use ecow::{EcoString, EcoVec};
13use rayon::prelude::*;
14use serde::{de::DeserializeOwned, *};
15
16use crate::{
17    algorithm::{
18        map::{MapKeys, EMPTY_NAN, TOMBSTONE_NAN},
19        ArrayCmpSlice,
20    },
21    cowslice::{cowslice, CowSlice},
22    fill::{Fill, FillValue},
23    grid_fmt::GridFmt,
24    Boxed, Complex, ExactDoubleIterator, FfiType, HandleKind, Shape, Value, WILDCARD_CHAR,
25    WILDCARD_NAN,
26};
27
28/// Uiua's array type
29#[derive(Clone, Serialize, Deserialize)]
30#[serde(
31    from = "ArrayRep<T>",
32    into = "ArrayRep<T>",
33    bound(
34        serialize = "T: ArrayValueSer + Serialize",
35        deserialize = "T: ArrayValueSer + Deserialize<'de>"
36    )
37)]
38#[repr(C)]
39pub struct Array<T> {
40    /// The array's shape
41    pub shape: Shape,
42    pub(crate) data: CowSlice<T>,
43    /// The array's metadata
44    pub meta: ArrayMeta,
45}
46
47/// Non-shape metadata for an array
48#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
49#[repr(C)]
50#[non_exhaustive]
51pub struct ArrayMetaInner {
52    /// The label
53    #[serde(default, skip_serializing_if = "Option::is_none")]
54    pub label: Option<EcoString>,
55    /// Flags for the array
56    #[serde(default, skip_serializing_if = "ArrayFlags::is_empty")]
57    pub flags: ArrayFlags,
58    /// The keys of a map array
59    #[serde(default, skip_serializing_if = "Option::is_none")]
60    pub map_keys: Option<MapKeys>,
61    /// The pointer value for FFI
62    #[serde(skip)]
63    pub pointer: Option<MetaPtr>,
64    /// The kind of system handle
65    #[serde(skip)]
66    pub handle_kind: Option<HandleKind>,
67}
68
69/// Default metadata for an array
70static DEFAULT_META_INNER: ArrayMetaInner = ArrayMetaInner {
71    label: None,
72    flags: ArrayFlags::NONE,
73    map_keys: None,
74    pointer: None,
75    handle_kind: None,
76};
77
78/// Non-shape metadata for an array
79///
80/// This wraps an optional pointer to a [`ArrayMetaInner`], whose fields can be accessed via `Deref` and `DerefMut`.
81///
82/// Mutably accessing the fields via the `DerefMut` implementation will populate the metadata.
83/// To avoid this, use [`ArrayMeta::get_mut`].
84#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
85#[serde(transparent)]
86#[repr(C)]
87pub struct ArrayMeta(Option<Arc<ArrayMetaInner>>);
88
89impl Deref for ArrayMeta {
90    type Target = ArrayMetaInner;
91    fn deref(&self) -> &Self::Target {
92        self.0.as_deref().unwrap_or(&DEFAULT_META_INNER)
93    }
94}
95
96impl DerefMut for ArrayMeta {
97    fn deref_mut(&mut self) -> &mut Self::Target {
98        Arc::make_mut(self.0.get_or_insert_with(Default::default))
99    }
100}
101
102impl ArrayMeta {
103    fn get_inner_mut(&mut self) -> Option<&mut ArrayMetaInner> {
104        self.0.as_mut().map(Arc::make_mut)
105    }
106    /// Get a mutable reference to the metadata, but only if any exists
107    pub fn get_mut(&mut self) -> Option<&mut Self> {
108        self.0.is_some().then_some(self)
109    }
110    /// Get a mutable reference to the map keys, if any exist
111    pub fn map_keys_mut(&mut self) -> Option<&mut MapKeys> {
112        self.get_inner_mut()?.map_keys.as_mut()
113    }
114    /// Check if the metadata is the default
115    pub fn is_default(&self) -> bool {
116        self.label.is_none()
117            && self.map_keys.is_none()
118            && self.handle_kind.is_none()
119            && self.pointer.is_none()
120            && self.flags.is_empty()
121    }
122    /// Check if the array is sorted ascending
123    pub fn is_sorted_up(&self) -> bool {
124        self.flags.contains(ArrayFlags::SORTED_UP)
125    }
126    /// Check if the array is sorted descending
127    pub fn is_sorted_down(&self) -> bool {
128        self.flags.contains(ArrayFlags::SORTED_DOWN)
129    }
130    /// Take the persistent metadata
131    pub fn take_per_meta(&mut self) -> PersistentMeta {
132        self.get_inner_mut()
133            .map(|inner| {
134                let label = inner.label.take();
135                let map_keys = inner.map_keys.take();
136                PersistentMeta { label, map_keys }
137            })
138            .unwrap_or_default()
139    }
140    /// Take the label from the metadata
141    pub fn take_label(&mut self) -> Option<EcoString> {
142        let inner = self.get_inner_mut()?;
143        if inner.label.is_some() {
144            inner.label.take()
145        } else {
146            None
147        }
148    }
149    /// Take the map keys from the metadata
150    pub fn take_map_keys(&mut self) -> Option<MapKeys> {
151        self.get_inner_mut()?.map_keys.take()
152    }
153    /// Take the sorted flags
154    pub fn take_sorted_flags(&mut self) -> ArrayFlags {
155        let flags = self.flags & ArrayFlags::SORTEDNESS;
156        self.flags &= !flags;
157        flags
158    }
159    /// Take the value flags
160    pub fn take_value_flags(&mut self) -> ArrayFlags {
161        let flags = self.flags & ArrayFlags::VALUE;
162        self.flags &= !ArrayFlags::VALUE;
163        flags
164    }
165    /// Set the label for the value
166    pub fn set_label(&mut self, label: Option<EcoString>) {
167        if label.is_none() && self.label.is_none() {
168            return;
169        }
170        self.label = label;
171    }
172    /// Set the persistent metadata
173    pub fn set_per_meta(&mut self, per_meta: PersistentMeta) {
174        if self.map_keys.is_some() != per_meta.map_keys.is_some() {
175            self.map_keys = per_meta.map_keys;
176        }
177        if self.label.is_some() != per_meta.label.is_some() {
178            self.label = per_meta.label;
179        }
180    }
181    /// Or the sorted flags
182    pub fn or_sorted_flags(&mut self, mut flags: ArrayFlags) {
183        flags &= ArrayFlags::SORTEDNESS;
184        if flags == ArrayFlags::NONE {
185            return;
186        }
187        self.flags |= flags;
188    }
189    /// Mark the array as sorted ascending
190    ///
191    /// It is a logic error to set this to `true` when it is not the case
192    pub(crate) fn mark_sorted_up(&mut self, sorted: bool) {
193        if sorted {
194            self.flags.insert(ArrayFlags::SORTED_UP);
195        } else if let Some(inner) = self.get_inner_mut() {
196            inner.flags.remove(ArrayFlags::SORTED_UP);
197        }
198    }
199    /// Mark the array as sorted descending
200    ///
201    /// It is a logic error to set this to `true` when it is not the case
202    pub(crate) fn mark_sorted_down(&mut self, sorted: bool) {
203        if sorted {
204            self.flags.insert(ArrayFlags::SORTED_DOWN);
205        } else if let Some(inner) = self.get_inner_mut() {
206            inner.flags.remove(ArrayFlags::SORTED_DOWN);
207        }
208    }
209    /// Combine the metadata with another
210    pub fn combine(&mut self, other: &Self) {
211        if let Some(other) = other.0.as_deref() {
212            self.flags &= other.flags;
213            self.map_keys = None;
214            if self.handle_kind != other.handle_kind {
215                self.handle_kind = None;
216            }
217        } else if let Some(inner) = self.get_inner_mut() {
218            inner.flags &= !ArrayFlags::VALUE;
219        }
220    }
221    /// Reset the flags
222    pub fn reset_flags(&mut self) {
223        self.flags.reset();
224    }
225}
226
227/// Array pointer metadata
228#[derive(Debug, Clone)]
229pub struct MetaPtr {
230    /// The pointer value
231    pub ptr: usize,
232    /// The type of value stored at the pointer when read
233    pub ty: FfiType,
234}
235
236impl MetaPtr {
237    /// Get a null metadata pointer
238    pub const fn null() -> Self {
239        Self {
240            ptr: 0,
241            ty: FfiType::Void,
242        }
243    }
244    /// Create a new metadata pointer
245    pub fn new(ptr: usize, ffi_type: FfiType) -> Self {
246        Self { ptr, ty: ffi_type }
247    }
248    /// Get the pointer as a raw pointer
249    pub fn get(&self) -> *const u8 {
250        self.ptr as *const _
251    }
252    /// Get the pointer as a raw pointer
253    pub fn get_mut(&self) -> *mut u8 {
254        self.ptr as *mut _
255    }
256}
257
258impl PartialEq for MetaPtr {
259    fn eq(&self, other: &Self) -> bool {
260        self.ptr == other.ptr
261    }
262}
263
264impl Eq for MetaPtr {}
265
266bitflags! {
267    /// Flags for an array
268    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
269    pub struct ArrayFlags: u8 {
270        /// No flags
271        const NONE = 0;
272        /// The array is boolean
273        const BOOLEAN = 1;
274        /// The array was *created from* a boolean
275        const BOOLEAN_LITERAL = 2;
276        /// The array is sorted ascending
277        const SORTED_UP = 4;
278        /// The array is sorted descending
279        const SORTED_DOWN = 8;
280        /// Value-related flags that are true about the rows as well
281        const VALUE = Self::BOOLEAN.bits() | Self::BOOLEAN_LITERAL.bits();
282        /// Sortedness-related flags
283        const SORTEDNESS = Self::SORTED_UP.bits() | Self::SORTED_DOWN.bits();
284    }
285}
286
287impl ArrayFlags {
288    /// Check if the array is boolean
289    pub fn is_boolean(self) -> bool {
290        self.contains(Self::BOOLEAN)
291    }
292    /// Reset all flags
293    pub fn reset(&mut self) {
294        *self = Self::NONE;
295    }
296    /// Reverse the sorted flags
297    pub fn reverse_sorted(&mut self) {
298        let sorted_up = self.contains(Self::SORTED_UP);
299        let sorted_down = self.contains(Self::SORTED_DOWN);
300        self.set(Self::SORTED_UP, sorted_down);
301        self.set(Self::SORTED_DOWN, sorted_up);
302    }
303}
304
305/// Array metadata that can be persisted across operations
306#[derive(Clone, Default)]
307pub struct PersistentMeta {
308    pub(crate) label: Option<EcoString>,
309    pub(crate) map_keys: Option<MapKeys>,
310}
311
312impl PersistentMeta {
313    /// XOR this metadata with another
314    pub fn xor(self, other: Self) -> Self {
315        Self {
316            label: self.label.xor(other.label),
317            map_keys: self.map_keys.xor(other.map_keys),
318        }
319    }
320    /// XOR several metadatas
321    pub fn xor_all(metas: impl IntoIterator<Item = Self>) -> Self {
322        let mut label = None;
323        let mut map_keys = None;
324        let mut set_label = false;
325        let mut set_map_keys = false;
326        for meta in metas {
327            if let Some(l) = meta.label {
328                if set_label {
329                    label = None;
330                } else {
331                    label = Some(l);
332                    set_label = true;
333                }
334            }
335            if let Some(keys) = meta.map_keys {
336                if set_map_keys {
337                    map_keys = None;
338                } else {
339                    map_keys = Some(keys);
340                    set_map_keys = true;
341                }
342            }
343        }
344        Self { label, map_keys }
345    }
346}
347
348impl<T: ArrayValue> Default for Array<T> {
349    fn default() -> Self {
350        Self {
351            shape: 0.into(),
352            data: CowSlice::new(),
353            meta: ArrayMeta::default(),
354        }
355    }
356}
357
358impl<T: ArrayValue> fmt::Debug for Array<T>
359where
360    Array<T>: GridFmt,
361{
362    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363        write!(f, "{}", self.grid_string(true))
364    }
365}
366
367impl<T: ArrayValue> fmt::Display for Array<T>
368where
369    Array<T>: GridFmt,
370{
371    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
372        match self.rank() {
373            0 => write!(f, "{}", self.data[0]),
374            1 => {
375                let (start, end) = T::format_delims();
376                write!(f, "{start}")?;
377                for (i, x) in self.data.iter().enumerate() {
378                    if i > 0 {
379                        write!(f, "{}", T::format_sep())?;
380                    }
381                    write!(f, "{x}")?;
382                }
383                write!(f, "{end}")
384            }
385            _ => {
386                write!(f, "\n{}", self.grid_string(false))
387            }
388        }
389    }
390}
391
392#[track_caller]
393#[inline(always)]
394pub(crate) fn validate_shape(_shape: &[usize], _len: usize) {
395    #[cfg(debug_assertions)]
396    {
397        let elems = if _shape.contains(&0) {
398            0
399        } else {
400            _shape.iter().product()
401        };
402        assert_eq!(
403            elems, _len,
404            "shape {_shape:?} does not match data length {_len}"
405        )
406    }
407}
408
409impl<T> Array<T> {
410    /// An empty list
411    pub const EMPTY_LIST: Self = Array {
412        shape: Shape::EMPTY_LIST,
413        data: CowSlice::new(),
414        meta: ArrayMeta(None),
415    };
416    #[track_caller]
417    /// Create an array from a shape and data
418    ///
419    /// # Panics
420    /// Panics in debug mode if the shape does not match the data length
421    pub fn new(shape: impl Into<Shape>, data: impl Into<CowSlice<T>>) -> Self {
422        let shape = shape.into();
423        let data = data.into();
424        validate_shape(&shape, data.len());
425        Self {
426            shape,
427            data,
428            meta: ArrayMeta::default(),
429        }
430    }
431    /// Get the number of rows in the array
432    #[inline(always)]
433    pub fn row_count(&self) -> usize {
434        self.shape.row_count()
435    }
436    /// Get the number of elements in the array
437    pub fn element_count(&self) -> usize {
438        self.data.len()
439    }
440    /// Get the number of elements in a row
441    #[inline(always)]
442    pub fn row_len(&self) -> usize {
443        self.shape.row_len()
444    }
445    /// Get the rank of the array
446    #[inline(always)]
447    pub fn rank(&self) -> usize {
448        self.shape.len()
449    }
450    /// Iterate over the elements of the array
451    pub fn elements(&self) -> impl ExactDoubleIterator<Item = &T> {
452        self.data.iter()
453    }
454    /// Get an iterator over the row slices of the array
455    pub fn row_slices(
456        &self,
457    ) -> impl ExactSizeIterator<Item = &[T]> + DoubleEndedIterator + Clone + Send + Sync
458    where
459        T: Send + Sync,
460    {
461        let row_len = self.row_len();
462        let data = self.data.as_slice();
463        // Safety: Just look at it
464        (0..self.row_count())
465            .map(move |i| unsafe { slice::from_raw_parts(data.as_ptr().add(i * row_len), row_len) })
466    }
467    /// Get a slice of a row
468    #[track_caller]
469    pub fn row_slice(&self, row: usize) -> &[T] {
470        let row_len = self.row_len();
471        &self.data[row * row_len..(row + 1) * row_len]
472    }
473}
474
475impl<T: Clone> Array<T> {
476    /// Get an iterator over the mutable row slices of the array
477    pub fn row_slices_mut(
478        &mut self,
479    ) -> impl ExactSizeIterator<Item = &mut [T]> + DoubleEndedIterator + Send + Sync
480    where
481        T: Send + Sync,
482    {
483        let row_count = self.row_count();
484        let row_len = self.row_len();
485        let data = self.data.as_mut_slice();
486        // Safety: Just look at it
487        (0..row_count).map(move |i| unsafe {
488            slice::from_raw_parts_mut(data.as_mut_ptr().add(i * row_len), row_len)
489        })
490    }
491    /// Get a row array
492    #[track_caller]
493    pub fn row(&self, row: usize) -> Self {
494        if self.rank() == 0 {
495            let mut row = self.clone();
496            row.meta.take_map_keys();
497            row.meta.take_label();
498            return row;
499        }
500        let row_count = self.row_count();
501        if row >= row_count {
502            panic!("row index out of bounds: {row} >= {row_count}");
503        }
504        let row_len = self.row_len();
505        let start = row * row_len;
506        let end = start + row_len;
507        let mut row = Self::new(&self.shape[1..], self.data.slice(start..end));
508        let value_flags = self.meta.flags & ArrayFlags::VALUE;
509        if value_flags != ArrayFlags::NONE {
510            row.meta.flags = value_flags;
511        }
512        row
513    }
514}
515
516impl<T: ArrayValue> Array<T> {
517    /// Create a scalar array
518    pub fn scalar(data: T) -> Self {
519        Self::new(Shape::SCALAR, cowslice![data])
520    }
521    /// Attempt to convert the array into a scalar
522    pub fn into_scalar(self) -> Result<T, Self> {
523        if self.shape.is_empty() {
524            Ok(self.data.into_iter().next().unwrap())
525        } else {
526            Err(self)
527        }
528    }
529    /// Attempt to get a reference to the scalar value
530    pub fn as_scalar(&self) -> Option<&T> {
531        if self.shape.is_empty() {
532            Some(&self.data[0])
533        } else {
534            None
535        }
536    }
537    /// Attempt to get a mutable reference to the scalar value
538    pub fn as_scalar_mut(&mut self) -> Option<&mut T> {
539        if self.shape.is_empty() {
540            Some(&mut self.data.as_mut_slice()[0])
541        } else {
542            None
543        }
544    }
545    /// Get an iterator over the row arrays of the array
546    pub fn rows(&self) -> impl ExactDoubleIterator<Item = Self> + '_ {
547        let value_flags = self.meta.flags & ArrayFlags::VALUE;
548        let set_value_flags = value_flags != ArrayFlags::NONE;
549        let row_len = self.row_len();
550        (0..self.row_count()).map(move |row| {
551            if self.rank() == 0 {
552                let mut row = self.clone();
553                row.meta.take_map_keys();
554                row.meta.take_label();
555                return row;
556            }
557            let start = row * row_len;
558            let end = start + row_len;
559            let mut row = Array::<T>::new(&self.shape[1..], self.data.slice(start..end));
560            if set_value_flags {
561                row.meta.flags = value_flags;
562            }
563            row
564        })
565    }
566    pub(crate) fn row_shaped_slice(&self, index: usize, row_shape: Shape) -> Self {
567        let row_len = row_shape.elements();
568        let start = index * row_len;
569        let end = start + row_len;
570        Self::new(row_shape, self.data.slice(start..end))
571    }
572    /// Get an iterator over the row arrays of the array that have the given shape
573    pub fn row_shaped_slices(
574        &self,
575        row_shape: Shape,
576    ) -> impl ExactDoubleIterator<Item = Self> + '_ {
577        let row_len = row_shape.elements();
578        let row_count = self.element_count() / row_len;
579        (0..row_count).map(move |i| {
580            let start = i * row_len;
581            let end = start + row_len;
582            Self::new(row_shape.clone(), self.data.slice(start..end))
583        })
584    }
585    /// Get an iterator over the row arrays of the array that have the given shape
586    pub fn into_row_shaped_slices(self, row_shape: Shape) -> impl DoubleEndedIterator<Item = Self> {
587        let row_len = row_shape.elements();
588        let zero_count = if row_len == 0 { self.row_count() } else { 0 };
589        let row_sh = row_shape.clone();
590        let nonzero = self
591            .data
592            .into_slices(row_len)
593            .map(move |data| Self::new(row_sh.clone(), data));
594        let zero = (0..zero_count).map(move |_| Self::new(row_shape.clone(), CowSlice::new()));
595        nonzero.chain(zero)
596    }
597    #[track_caller]
598    pub(crate) fn depth_row(&self, depth: usize, row: usize) -> Self {
599        if self.rank() <= depth {
600            let mut row = self.clone();
601            row.meta.take_map_keys();
602            row.meta.take_label();
603            return row;
604        }
605        let row_count: usize = self.shape[..depth + 1].iter().product();
606        if row >= row_count {
607            panic!("row index out of bounds: {row} >= {row_count}");
608        }
609        let row_len: usize = self.shape[depth + 1..].iter().product();
610        let start = row * row_len;
611        let end = start + row_len;
612        Self::new(&self.shape[depth + 1..], self.data.slice(start..end))
613    }
614    #[track_caller]
615    pub(crate) fn depth_rows(&self, depth: usize) -> impl ExactDoubleIterator<Item = Self> + '_ {
616        let row_count: usize = self.shape[..depth].iter().product();
617        let row_len: usize = self.shape[depth..].iter().product();
618        (0..row_count).map(move |row| {
619            let start = row * row_len;
620            let end = start + row_len;
621            Self::new(&self.shape[depth..], self.data.slice(start..end))
622        })
623    }
624    #[track_caller]
625    /// Create an array that is a slice of this array's rows
626    ///
627    /// Generally doesn't allocate
628    ///
629    /// - `start` must be <= `end`
630    /// - `start` must be < `self.row_count()`
631    /// - `end` must be <= `self.row_count()`
632    pub fn slice_rows(&self, start: usize, end: usize) -> Self {
633        assert!(start <= end);
634        assert!(start < self.row_count());
635        assert!(end <= self.row_count());
636        let row_len = self.row_len();
637        let mut shape = self.shape.clone();
638        shape[0] = end - start;
639        let start = start * row_len;
640        let end = end * row_len;
641        Self::new(shape, self.data.slice(start..end))
642    }
643    /// Consume the array and get an iterator over its rows
644    pub fn into_rows(self) -> impl ExactDoubleIterator<Item = Self> {
645        (0..self.row_count()).map(move |i| self.row(i))
646    }
647    pub(crate) fn first_dim_zero(&self) -> Self {
648        if self.rank() == 0 {
649            return self.clone();
650        }
651        let mut shape = self.shape.clone();
652        shape[0] = 0;
653        Array::new(shape, CowSlice::new())
654    }
655    /// Get a pretty-printed string representing the array
656    ///
657    /// This is what is printed by the `&s` function
658    pub fn show(&self) -> String {
659        self.grid_string(true)
660    }
661    pub(crate) fn pop_row(&mut self) -> Option<Self> {
662        if self.row_count() == 0 {
663            return None;
664        }
665        let data = self.data.split_off(self.data.len() - self.row_len());
666        self.shape[0] -= 1;
667        let shape: Shape = self.shape[1..].into();
668        self.validate();
669        Some(Self::new(shape, data))
670    }
671    /// Get a mutable slice of a row
672    #[track_caller]
673    pub fn row_slice_mut(&mut self, row: usize) -> &mut [T] {
674        let row_len = self.row_len();
675        &mut self.data.as_mut_slice()[row * row_len..(row + 1) * row_len]
676    }
677    /// Set the sortedness flags according to the array's data
678    pub fn derive_sortedness(&mut self) {
679        if !self.data.iter().all(|x| x.is_sortable()) {
680            return;
681        }
682        let mut sorted_up = true;
683        let mut sorted_down = true;
684        let mut rows = self.row_slices().map(ArrayCmpSlice);
685        if let Some(mut prev) = rows.next() {
686            for row in rows {
687                match prev.cmp(&row) {
688                    Ordering::Equal => {}
689                    Ordering::Less => {
690                        sorted_down = false;
691                        if !sorted_up {
692                            break;
693                        }
694                    }
695                    Ordering::Greater => {
696                        sorted_up = false;
697                        if !sorted_down {
698                            break;
699                        }
700                    }
701                }
702                prev = row;
703            }
704        } else {
705            drop(rows);
706        }
707        self.meta.mark_sorted_up(sorted_up);
708        self.meta.mark_sorted_down(sorted_down);
709    }
710    #[track_caller]
711    #[inline(always)]
712    /// Debug-only to ensure the array's invariants are upheld
713    pub(crate) fn validate(&self) {
714        #[cfg(debug_assertions)]
715        {
716            validate_shape(&self.shape, self.data.len());
717            let is_sorted_up = self.meta.is_sorted_up();
718            let is_sorted_down = self.meta.is_sorted_down();
719            if is_sorted_up || is_sorted_down {
720                let mut rows = (0..self.row_count()).map(|i| self.row_slice(i));
721                if let Some(prev) = rows.next() {
722                    let mut prev = ArrayCmpSlice(prev);
723                    for row in rows {
724                        let row = ArrayCmpSlice(row);
725                        assert!(
726                            !is_sorted_up || prev <= row,
727                            "{} array marked as sorted up is not. {:?} > {:?}.",
728                            T::NAME,
729                            prev.0,
730                            row.0
731                        );
732                        assert!(
733                            !is_sorted_down || prev >= row,
734                            "{} array marked as sorted down is not. {:?} < {:?}.",
735                            T::NAME,
736                            prev.0,
737                            row.0
738                        );
739                        prev = row;
740                    }
741                }
742            }
743            T::dbg_validate(self);
744        }
745    }
746}
747
748impl<T: Clone> Array<T> {
749    /// Convert the elements of the array
750    #[inline(always)]
751    pub fn convert<U>(self) -> Array<U>
752    where
753        T: Into<U> + 'static,
754        U: Clone + 'static,
755    {
756        if TypeId::of::<T>() == TypeId::of::<U>() {
757            unsafe { std::mem::transmute::<Array<T>, Array<U>>(self) }
758        } else {
759            self.convert_with(Into::into)
760        }
761    }
762    /// Convert the elements of the array with a function
763    pub fn convert_with<U: Clone>(self, f: impl FnMut(T) -> U) -> Array<U> {
764        Array {
765            shape: self.shape,
766            data: self.data.into_iter().map(f).collect(),
767            meta: self.meta,
768        }
769    }
770    /// Convert the elements of the array with a fallible function
771    pub fn try_convert_with<U: Clone, E>(
772        self,
773        f: impl FnMut(T) -> Result<U, E>,
774    ) -> Result<Array<U>, E> {
775        Ok(Array {
776            shape: self.shape,
777            data: self.data.into_iter().map(f).collect::<Result<_, _>>()?,
778            meta: self.meta,
779        })
780    }
781    /// Convert the elements of the array without consuming it
782    pub fn convert_ref<U>(&self) -> Array<U>
783    where
784        T: Into<U>,
785        U: Clone,
786    {
787        self.convert_ref_with(Into::into)
788    }
789    /// Convert the elements of the array with a function without consuming it
790    pub fn convert_ref_with<U: Clone>(&self, f: impl FnMut(T) -> U) -> Array<U> {
791        Array {
792            shape: self.shape.clone(),
793            data: self.data.iter().cloned().map(f).collect(),
794            meta: self.meta.clone(),
795        }
796    }
797    #[track_caller]
798    #[allow(dead_code)]
799    pub(crate) fn depth_slices(&self, depth: usize) -> impl ExactDoubleIterator<Item = &[T]> {
800        let row_len: usize = self.shape[depth..].iter().product();
801        self.data.chunks_exact(row_len)
802    }
803    #[track_caller]
804    #[allow(dead_code)]
805    pub(crate) fn depth_slices_mut(
806        &mut self,
807        depth: usize,
808    ) -> impl ExactDoubleIterator<Item = &mut [T]> {
809        let row_len: usize = self.shape[depth..].iter().product();
810        self.data.as_mut_slice().chunks_exact_mut(row_len)
811    }
812}
813
814impl Array<u8> {
815    pub(crate) fn json_bool(b: bool) -> Self {
816        let mut arr = Self::from(b);
817        arr.meta.flags |= ArrayFlags::BOOLEAN_LITERAL;
818        arr
819    }
820}
821
822impl Array<Boxed> {
823    /// Attempt to unbox a scalar box array
824    pub fn into_unboxed(self) -> Result<Value, Self> {
825        match self.into_scalar() {
826            Ok(v) => Ok(v.0),
827            Err(a) => Err(a),
828        }
829    }
830    /// Attempt to unbox a scalar box array
831    pub fn as_unboxed(&self) -> Option<&Value> {
832        self.as_scalar().map(|v| &v.0)
833    }
834    /// Attempt to unbox a scalar box array
835    pub fn as_unboxed_mut(&mut self) -> Option<&mut Value> {
836        self.as_scalar_mut().map(|v| &mut v.0)
837    }
838}
839
840impl<T: ArrayValue + ArrayCmp<U>, U: ArrayValue> PartialEq<Array<U>> for Array<T> {
841    fn eq(&self, other: &Array<U>) -> bool {
842        if self.shape != other.shape {
843            return false;
844        }
845        if self.meta.map_keys != other.meta.map_keys {
846            return false;
847        }
848        self.data
849            .iter()
850            .zip(&other.data)
851            .all(|(a, b)| a.array_eq(b))
852    }
853}
854
855impl<T: ArrayValue> Eq for Array<T> {}
856
857impl<T: ArrayValue + ArrayCmp<U>, U: ArrayValue> PartialOrd<Array<U>> for Array<T> {
858    fn partial_cmp(&self, other: &Array<U>) -> Option<Ordering> {
859        let rank_cmp = self.rank().cmp(&other.rank());
860        if rank_cmp != Ordering::Equal {
861            return Some(rank_cmp);
862        }
863        let cmp = self
864            .data
865            .iter()
866            .zip(&other.data)
867            .map(|(a, b)| a.array_cmp(b))
868            .find(|o| o != &Ordering::Equal)
869            .unwrap_or_else(|| self.shape.cmp(&other.shape));
870        Some(cmp)
871    }
872}
873
874impl<T: ArrayValue> Ord for Array<T> {
875    fn cmp(&self, other: &Self) -> Ordering {
876        self.partial_cmp(other).unwrap()
877    }
878}
879
880impl<T: ArrayValue> Hash for Array<T> {
881    fn hash<H: Hasher>(&self, hasher: &mut H) {
882        if let Some(keys) = &self.meta.map_keys {
883            keys.hash(hasher);
884        }
885        T::TYPE_ID.hash(hasher);
886        if let Some(scalar) = self.as_scalar() {
887            if let Some(value) = scalar.nested_value() {
888                value.hash(hasher);
889                return;
890            }
891        }
892        self.shape.hash(hasher);
893        self.data.iter().for_each(|x| x.array_hash(hasher));
894    }
895}
896
897impl<T: ArrayValue> From<T> for Array<T> {
898    fn from(data: T) -> Self {
899        Self::scalar(data)
900    }
901}
902
903impl<T: ArrayValue> From<EcoVec<T>> for Array<T> {
904    fn from(data: EcoVec<T>) -> Self {
905        Self::new(data.len(), data)
906    }
907}
908
909impl<T: ArrayValue> From<CowSlice<T>> for Array<T> {
910    fn from(data: CowSlice<T>) -> Self {
911        Self::new(data.len(), data)
912    }
913}
914
915impl<'a, T: ArrayValue> From<&'a [T]> for Array<T> {
916    fn from(data: &'a [T]) -> Self {
917        Self::new(data.len(), data)
918    }
919}
920
921impl<T: ArrayValue> FromIterator<T> for Array<T> {
922    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
923        Self::from(iter.into_iter().collect::<CowSlice<T>>())
924    }
925}
926
927impl From<String> for Array<char> {
928    fn from(s: String) -> Self {
929        s.chars().collect()
930    }
931}
932
933impl From<&str> for Array<char> {
934    fn from(s: &str) -> Self {
935        s.chars().collect()
936    }
937}
938
939impl From<Vec<bool>> for Array<u8> {
940    fn from(data: Vec<bool>) -> Self {
941        Self::new(
942            data.len(),
943            data.into_iter().map(u8::from).collect::<CowSlice<_>>(),
944        )
945    }
946}
947
948impl From<bool> for Array<u8> {
949    fn from(data: bool) -> Self {
950        let mut arr = Self::new(Shape::SCALAR, cowslice![u8::from(data)]);
951        arr.meta.flags |= ArrayFlags::BOOLEAN;
952        arr
953    }
954}
955
956impl From<Vec<usize>> for Array<f64> {
957    fn from(data: Vec<usize>) -> Self {
958        Self::new(
959            data.len(),
960            data.into_iter().map(|u| u as f64).collect::<CowSlice<_>>(),
961        )
962    }
963}
964
965impl FromIterator<String> for Array<Boxed> {
966    fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
967        Array::from(
968            iter.into_iter()
969                .map(Value::from)
970                .map(Boxed)
971                .collect::<CowSlice<_>>(),
972        )
973    }
974}
975
976impl<'a> FromIterator<&'a str> for Array<Boxed> {
977    fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> Self {
978        Array::from(
979            iter.into_iter()
980                .map(Value::from)
981                .map(Boxed)
982                .collect::<CowSlice<_>>(),
983        )
984    }
985}
986
987/// A trait for types that can be used as array elements
988#[allow(unused_variables)]
989pub trait ArrayValue:
990    Default + Clone + fmt::Debug + fmt::Display + GridFmt + ArrayCmp + Send + Sync + 'static
991{
992    /// The type name
993    const NAME: &'static str;
994    /// A glyph indicating the type
995    const SYMBOL: char;
996    /// An ID for the type
997    const TYPE_ID: u8;
998    /// Get the scalar fill value from the environment
999    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str>;
1000    /// Get the array fill value from the environment
1001    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str>;
1002    /// Hash the value
1003    fn array_hash<H: Hasher>(&self, hasher: &mut H);
1004    /// Get the proxy value
1005    fn proxy() -> Self;
1006    /// Get a nested value
1007    fn nested_value(&self) -> Option<&Value> {
1008        None
1009    }
1010    /// Check if this element has the wildcard value
1011    fn has_wildcard(&self) -> bool {
1012        false
1013    }
1014    /// Sort a list of this type
1015    fn sort_list(list: &mut [Self], up: bool) {
1016        default_sort_list(list, up)
1017    }
1018    /// Whether this value can be sorted
1019    fn is_sortable(&self) -> bool {
1020        true
1021    }
1022    /// Validate array correctness in debug mode
1023    fn dbg_validate(arr: &Array<Self>) {}
1024}
1025
1026fn default_sort_list<T: ArrayCmp + Send>(list: &mut [T], up: bool) {
1027    if up {
1028        list.par_sort_unstable_by(T::array_cmp);
1029    } else {
1030        list.par_sort_unstable_by(|a, b| b.array_cmp(a));
1031    }
1032}
1033
1034impl ArrayValue for f64 {
1035    const NAME: &'static str = "number";
1036    const SYMBOL: char = 'ℝ';
1037    const TYPE_ID: u8 = 0;
1038    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1039        fill.num_scalar()
1040    }
1041    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1042        fill.num_array()
1043    }
1044    fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1045        let v = if self.to_bits() == EMPTY_NAN.to_bits() {
1046            EMPTY_NAN
1047        } else if self.to_bits() == TOMBSTONE_NAN.to_bits() {
1048            TOMBSTONE_NAN
1049        } else if self.to_bits() == WILDCARD_NAN.to_bits() {
1050            WILDCARD_NAN
1051        } else if self.is_nan() {
1052            f64::NAN
1053        } else if *self == 0.0 && self.is_sign_negative() {
1054            0.0
1055        } else {
1056            *self
1057        };
1058        v.to_bits().hash(hasher)
1059    }
1060    fn proxy() -> Self {
1061        0.0
1062    }
1063    fn has_wildcard(&self) -> bool {
1064        self.to_bits() == WILDCARD_NAN.to_bits()
1065    }
1066    fn is_sortable(&self) -> bool {
1067        !self.is_nan()
1068    }
1069}
1070
1071#[cfg(test)]
1072#[test]
1073fn f64_summarize() {
1074    assert_eq!(f64::summarize(&[2.0, 6.0, 1.0]), "1-6 μ3");
1075}
1076
1077impl ArrayValue for u8 {
1078    const NAME: &'static str = "number";
1079    const SYMBOL: char = 'ℝ';
1080    const TYPE_ID: u8 = 0;
1081    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1082        fill.byte_scalar()
1083    }
1084    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1085        fill.byte_array()
1086    }
1087    fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1088        (*self as f64).to_bits().hash(hasher)
1089    }
1090    fn proxy() -> Self {
1091        0
1092    }
1093    fn sort_list(list: &mut [Self], up: bool) {
1094        let mut counts: [usize; 256] = [0; 256];
1095        for x in &mut *list {
1096            counts[*x as usize] += 1;
1097        }
1098        let mut i = 0;
1099        if up {
1100            for (j, &count) in counts.iter().enumerate() {
1101                let n = j as u8;
1102                for _ in 0..count {
1103                    list[i] = n;
1104                    i += 1;
1105                }
1106            }
1107        } else {
1108            let offset = list.len().saturating_sub(1);
1109            for (j, &count) in counts.iter().enumerate() {
1110                let n = j as u8;
1111                for _ in 0..count {
1112                    list[offset - i] = n;
1113                    i += 1;
1114                }
1115            }
1116        }
1117    }
1118    #[track_caller]
1119    fn dbg_validate(arr: &Array<Self>) {
1120        if arr.meta.flags.is_boolean() {
1121            if let Some(b) = arr.data.iter().find(|&b| *b > 1) {
1122                panic!("Array marked as boolean contains {b}")
1123            }
1124        }
1125    }
1126}
1127
1128impl ArrayValue for char {
1129    const NAME: &'static str = "character";
1130    const SYMBOL: char = '@';
1131    const TYPE_ID: u8 = 1;
1132    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1133        fill.char_scalar()
1134    }
1135    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1136        fill.char_array()
1137    }
1138    fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1139        self.hash(hasher)
1140    }
1141    fn proxy() -> Self {
1142        ' '
1143    }
1144    fn has_wildcard(&self) -> bool {
1145        *self == WILDCARD_CHAR
1146    }
1147}
1148
1149impl ArrayValue for Boxed {
1150    const NAME: &'static str = "box";
1151    const SYMBOL: char = '□';
1152    const TYPE_ID: u8 = 2;
1153    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1154        fill.box_scalar()
1155    }
1156    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1157        fill.box_array()
1158    }
1159    fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1160        self.0.hash(hasher);
1161    }
1162    fn proxy() -> Self {
1163        Boxed(Array::<f64>::new(0, []).into())
1164    }
1165    fn nested_value(&self) -> Option<&Value> {
1166        Some(&self.0)
1167    }
1168    fn has_wildcard(&self) -> bool {
1169        self.0.has_wildcard()
1170    }
1171}
1172
1173impl ArrayValue for Complex {
1174    const NAME: &'static str = "complex";
1175    const SYMBOL: char = 'ℂ';
1176    const TYPE_ID: u8 = 3;
1177    fn get_scalar_fill(fill: &Fill) -> Result<FillValue<Self>, &'static str> {
1178        fill.complex_scalar()
1179    }
1180    fn get_array_fill(fill: &Fill) -> Result<FillValue<Array<Self>>, &'static str> {
1181        fill.complex_array()
1182    }
1183    fn array_hash<H: Hasher>(&self, hasher: &mut H) {
1184        for n in [self.re, self.im] {
1185            n.array_hash(hasher);
1186        }
1187    }
1188    fn proxy() -> Self {
1189        Complex::new(0.0, 0.0)
1190    }
1191}
1192
1193/// Trait for [`ArrayValue`]s that are real numbers
1194pub trait RealArrayValue: ArrayValue + Copy {
1195    /// Whether the value is an integer
1196    fn is_int(&self) -> bool;
1197    /// Convert the value to an `f64`
1198    fn to_f64(&self) -> f64;
1199}
1200
1201impl RealArrayValue for f64 {
1202    fn is_int(&self) -> bool {
1203        self.fract().abs() < f64::EPSILON
1204    }
1205    fn to_f64(&self) -> f64 {
1206        *self
1207    }
1208}
1209
1210impl RealArrayValue for u8 {
1211    fn is_int(&self) -> bool {
1212        true
1213    }
1214    fn to_f64(&self) -> f64 {
1215        *self as f64
1216    }
1217}
1218
1219/// Trait for comparing array elements
1220pub trait ArrayCmp<U = Self> {
1221    /// Compare two elements
1222    fn array_cmp(&self, other: &U) -> Ordering;
1223    /// Check if two elements are equal
1224    fn array_eq(&self, other: &U) -> bool {
1225        self.array_cmp(other) == Ordering::Equal
1226    }
1227}
1228
1229impl ArrayCmp for f64 {
1230    fn array_cmp(&self, other: &Self) -> Ordering {
1231        self.partial_cmp(other).unwrap_or_else(|| {
1232            if self.to_bits() == WILDCARD_NAN.to_bits() || other.to_bits() == WILDCARD_NAN.to_bits()
1233            {
1234                Ordering::Equal
1235            } else {
1236                self.is_nan().cmp(&other.is_nan())
1237            }
1238        })
1239    }
1240}
1241
1242impl ArrayCmp for u8 {
1243    fn array_cmp(&self, other: &Self) -> Ordering {
1244        self.cmp(other)
1245    }
1246}
1247
1248impl ArrayCmp for Complex {
1249    fn array_cmp(&self, other: &Self) -> Ordering {
1250        self.partial_cmp(other).unwrap_or_else(|| {
1251            (self.re.is_nan(), self.im.is_nan()).cmp(&(other.re.is_nan(), other.im.is_nan()))
1252        })
1253    }
1254}
1255
1256impl ArrayCmp for char {
1257    fn array_eq(&self, other: &Self) -> bool {
1258        *self == *other || *self == WILDCARD_CHAR || *other == WILDCARD_CHAR
1259    }
1260    fn array_cmp(&self, other: &Self) -> Ordering {
1261        if *self == WILDCARD_CHAR || *other == WILDCARD_CHAR {
1262            Ordering::Equal
1263        } else {
1264            self.cmp(other)
1265        }
1266    }
1267}
1268
1269impl ArrayCmp for Boxed {
1270    fn array_cmp(&self, other: &Self) -> Ordering {
1271        self.cmp(other)
1272    }
1273}
1274
1275impl ArrayCmp<f64> for u8 {
1276    fn array_cmp(&self, other: &f64) -> Ordering {
1277        (*self as f64).array_cmp(other)
1278    }
1279}
1280
1281impl ArrayCmp<u8> for f64 {
1282    fn array_cmp(&self, other: &u8) -> Ordering {
1283        self.array_cmp(&(*other as f64))
1284    }
1285}
1286
1287/// A formattable shape
1288#[derive(Clone, Copy, PartialEq, Eq)]
1289pub struct FormatShape<'a, T = usize>(pub &'a [T]);
1290
1291impl<T: fmt::Display> fmt::Debug for FormatShape<'_, T> {
1292    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1293        write!(f, "{self}")
1294    }
1295}
1296
1297impl<T: fmt::Display> fmt::Display for FormatShape<'_, T> {
1298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1299        write!(f, "[")?;
1300        for (i, dim) in self.0.iter().enumerate() {
1301            if i > 0 {
1302                write!(f, " × ")?;
1303            }
1304            write!(f, "{dim}")?;
1305        }
1306        write!(f, "]")
1307    }
1308}
1309
1310#[derive(Debug, Clone, Serialize, Deserialize)]
1311#[serde(untagged)]
1312#[serde(bound(
1313    serialize = "T: ArrayValueSer + Serialize",
1314    deserialize = "T: ArrayValueSer + Deserialize<'de>"
1315))]
1316enum ArrayRep<T: ArrayValueSer> {
1317    List(T::Collection),
1318    Scalar(T::Scalar),
1319    Map(Shape, Value, T::Collection),
1320    Metaless(Shape, T::Collection),
1321    Full(Shape, T::Collection, ArrayMeta),
1322}
1323
1324impl<T: ArrayValueSer> From<ArrayRep<T>> for Array<T> {
1325    fn from(rep: ArrayRep<T>) -> Self {
1326        let mut arr = match rep {
1327            ArrayRep::Scalar(data) => Self::new([], [data.into()]),
1328            ArrayRep::List(data) => {
1329                let data = T::make_data(data);
1330                Self::new(data.len(), data)
1331            }
1332            ArrayRep::Map(shape, keys, data) => {
1333                let data = T::make_data(data);
1334                let mut arr = Self::new(shape, data);
1335                _ = arr.map(keys, &());
1336                arr
1337            }
1338            ArrayRep::Metaless(shape, data) => {
1339                let data = T::make_data(data);
1340                Self::new(shape, data)
1341            }
1342            ArrayRep::Full(shape, data, meta) => {
1343                let data = T::make_data(data);
1344                Self { shape, data, meta }
1345            }
1346        };
1347
1348        // Update sortedness flags
1349        let mut is_sorted_up = true;
1350        let mut is_sorted_down = true;
1351        {
1352            let mut rows = arr.row_slices();
1353            if let Some(mut curr) = rows.next() {
1354                for row in rows {
1355                    if !is_sorted_up && !is_sorted_down {
1356                        break;
1357                    }
1358                    match ArrayCmpSlice(curr).cmp(&ArrayCmpSlice(row)) {
1359                        Ordering::Equal => {}
1360                        Ordering::Less => is_sorted_down = false,
1361                        Ordering::Greater => is_sorted_up = false,
1362                    }
1363                    curr = row;
1364                }
1365            }
1366        }
1367        arr.meta.mark_sorted_up(is_sorted_up);
1368        arr.meta.mark_sorted_down(is_sorted_down);
1369        arr
1370    }
1371}
1372
1373impl<T: ArrayValueSer> From<Array<T>> for ArrayRep<T> {
1374    fn from(mut arr: Array<T>) -> Self {
1375        if let Some(inner) = (arr.meta.0.take()).filter(|meta| **meta != DEFAULT_META_INNER) {
1376            let mut inner = Arc::unwrap_or_clone(inner);
1377            let map_keys = inner.map_keys.take();
1378            if inner == DEFAULT_META_INNER {
1379                if let Some(map_keys) = map_keys {
1380                    let keys = map_keys.normalized();
1381                    return ArrayRep::Map(arr.shape, keys, T::make_collection(arr.data));
1382                }
1383            } else {
1384                inner.map_keys = map_keys;
1385            }
1386            inner.flags = ArrayFlags::empty();
1387            if inner != DEFAULT_META_INNER {
1388                return ArrayRep::Full(
1389                    arr.shape,
1390                    T::make_collection(arr.data),
1391                    ArrayMeta(Some(inner.into())),
1392                );
1393            }
1394        }
1395        match arr.rank() {
1396            0 if !T::no_scalar() => ArrayRep::Scalar(arr.data[0].clone().into()),
1397            1 => ArrayRep::List(T::make_collection(arr.data)),
1398            _ => ArrayRep::Metaless(arr.shape, T::make_collection(arr.data)),
1399        }
1400    }
1401}
1402
1403trait ArrayValueSer: ArrayValue + fmt::Debug {
1404    type Scalar: Serialize + DeserializeOwned + fmt::Debug + From<Self> + Into<Self>;
1405    type Collection: Serialize + DeserializeOwned + fmt::Debug;
1406    fn make_collection(data: CowSlice<Self>) -> Self::Collection;
1407    fn make_data(collection: Self::Collection) -> CowSlice<Self>;
1408    /// Do not use the [`ArrayRep::Scalar`] variant
1409    fn no_scalar() -> bool {
1410        false
1411    }
1412}
1413
1414impl ArrayValueSer for u8 {
1415    type Scalar = u8;
1416    type Collection = CowSlice<u8>;
1417    fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1418        data
1419    }
1420    fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1421        collection
1422    }
1423}
1424
1425#[derive(Debug, Clone, Serialize, Deserialize)]
1426enum BoxCollection {
1427    #[serde(rename = "empty_boxes")]
1428    Empty([Boxed; 0]),
1429    #[serde(untagged)]
1430    List(CowSlice<Boxed>),
1431}
1432
1433impl ArrayValueSer for Boxed {
1434    type Scalar = Boxed;
1435    type Collection = BoxCollection;
1436    fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1437        if data.is_empty() {
1438            BoxCollection::Empty([])
1439        } else {
1440            BoxCollection::List(data)
1441        }
1442    }
1443    fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1444        match collection {
1445            BoxCollection::Empty(_) => CowSlice::new(),
1446            BoxCollection::List(data) => data,
1447        }
1448    }
1449}
1450
1451#[derive(Debug, Clone, Serialize, Deserialize)]
1452enum ComplexCollection {
1453    #[serde(rename = "empty_complex")]
1454    Empty([Complex; 0]),
1455    #[serde(untagged)]
1456    List(CowSlice<Complex>),
1457}
1458
1459impl ArrayValueSer for Complex {
1460    type Scalar = Complex;
1461    type Collection = ComplexCollection;
1462    fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1463        if data.is_empty() {
1464            ComplexCollection::Empty([])
1465        } else {
1466            ComplexCollection::List(data)
1467        }
1468    }
1469    fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1470        match collection {
1471            ComplexCollection::Empty(_) => CowSlice::new(),
1472            ComplexCollection::List(data) => data,
1473        }
1474    }
1475    fn no_scalar() -> bool {
1476        true
1477    }
1478}
1479
1480impl ArrayValueSer for f64 {
1481    type Scalar = F64Rep;
1482    type Collection = Vec<F64Rep>;
1483    fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1484        data.iter().map(|&n| n.into()).collect()
1485    }
1486    fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1487        collection.into_iter().map(f64::from).collect()
1488    }
1489}
1490
1491impl ArrayValueSer for char {
1492    type Scalar = char;
1493    type Collection = String;
1494    fn make_collection(data: CowSlice<Self>) -> Self::Collection {
1495        data.iter().collect()
1496    }
1497    fn make_data(collection: Self::Collection) -> CowSlice<Self> {
1498        collection.chars().collect()
1499    }
1500    fn no_scalar() -> bool {
1501        true
1502    }
1503}
1504
1505#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
1506enum F64Rep {
1507    #[serde(rename = "NaN")]
1508    NaN,
1509    #[serde(rename = "empty")]
1510    MapEmpty,
1511    #[serde(rename = "tomb")]
1512    MapTombstone,
1513    #[serde(rename = "∞")]
1514    Infinity,
1515    #[serde(rename = "-∞")]
1516    NegInfinity,
1517    #[serde(untagged)]
1518    Num(f64),
1519}
1520
1521impl From<f64> for F64Rep {
1522    fn from(n: f64) -> Self {
1523        if n.is_nan() {
1524            if n.to_bits() == EMPTY_NAN.to_bits() {
1525                Self::MapEmpty
1526            } else if n.to_bits() == TOMBSTONE_NAN.to_bits() {
1527                Self::MapTombstone
1528            } else {
1529                Self::NaN
1530            }
1531        } else if n.is_infinite() {
1532            if n.is_sign_positive() {
1533                Self::Infinity
1534            } else {
1535                Self::NegInfinity
1536            }
1537        } else {
1538            Self::Num(n)
1539        }
1540    }
1541}
1542
1543impl From<F64Rep> for f64 {
1544    fn from(rep: F64Rep) -> Self {
1545        match rep {
1546            F64Rep::NaN => f64::NAN,
1547            F64Rep::MapEmpty => EMPTY_NAN,
1548            F64Rep::MapTombstone => TOMBSTONE_NAN,
1549            F64Rep::Infinity => f64::INFINITY,
1550            F64Rep::NegInfinity => f64::NEG_INFINITY,
1551            F64Rep::Num(n) => n,
1552        }
1553    }
1554}