Skip to main content

tango/
buf.rs

1//! Typed buffers, octets being a `Buf<u8, 1>`, which is what a backend receives a message
2//! into.
3//!
4//! A [`Buf`] is a typed, N-dimensional array of values, whose dimensions are fixed once it
5//! is built. It has no lifetime: it holds a reference to a counted storage that every clone
6//! and every slice shares, so that the buffer a message is received into can be handed out
7//! in pieces, cast to the types of the values it holds, all the way up to the user, without
8//! copying any of it.
9//!
10//! A [`BufMut`] is a buffer that is statically the only reference to its storage, which is
11//! what allows writing to it, and growing it along one dimension, like a `Vec`, without ever
12//! checking whether its storage is shared. A [`Buf`] turns into one with copy-on-write, see
13//! [`Buf::make_mut`] and [`Buf::into_mut`], copying only its own values when its storage is
14//! shared, or without, see [`Buf::get_mut`] and [`Buf::try_into_mut`], and a [`BufMut`]
15//! turns back into a [`Buf`] to be shared, see [`BufMut::freeze`].
16//!
17//! # Alignment
18//!
19//! Storages are currently aligned on 8 octets, so that a buffer starting where its storage
20//! starts, such as one that was just allocated, is aligned for every [`PackedElement`] and
21//! casts to any of them without copying. This is an implementation detail, which is not
22//! guaranteed to stay the same across versions: what depends on the alignment of some
23//! values checks it, like [`Buf::cast`], which copies the values when they are not aligned
24//! for their new type.
25
26use std::borrow::Cow;
27use std::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
28use std::mem::{self, ManuallyDrop, MaybeUninit};
29use std::fmt::{self, Debug, LowerHex, UpperHex};
30use std::ops::{Bound, Range, RangeBounds};
31use std::alloc::{self, Layout};
32use std::ptr::{self, NonNull};
33use std::num::NonZero;
34use std::marker::PhantomData;
35use std::{slice, str};
36
37use crate::error::{Error, ErrorKind};
38use crate::value::DevEnum;
39use crate::dev::DevState;
40
41
42// =========================== //
43//           Storage           //
44// =========================== //
45
46/// The header of a storage, directly followed by its data, in units of 8 octets so that
47/// the data is aligned for every [`PackedElement`].
48#[repr(C)]
49struct HeapHeader {
50    /// Number of handles on this storage, the storage being freed when it drops to zero.
51    count: AtomicUsize,
52    /// Capacity of the data, in units of 8 octets.
53    cap: usize,
54    /// The side allocations freed together with this storage, see [`SideHeader`].
55    side: AtomicPtr<SideHeader>,
56}
57
58/// The header of a side allocation, directly followed by its payload: something a [`Buf`]
59/// needs beside its values, such as the spans of its strings, which lives exactly as long
60/// as the storage it is attached to, and therefore needs no count of its own.
61#[repr(C)]
62struct SideHeader {
63    /// The next side allocation of the same storage.
64    next: *mut SideHeader,
65    /// Size of the payload, in octets.
66    size: usize,
67}
68
69/// The alignment of the data of a storage and of the payload of a side allocation, which
70/// is not part of the API, see the [module](self) documentation.
71const ALIGN: usize = 8;
72
73/// What an allocation fails with: no layout at all for a capacity that large, or the layout
74/// the allocator failed on.
75type AllocResult<T> = Result<T, Option<Layout>>;
76
77/// Unwrap an allocation the way the standard collections do: a panic when the capacity
78/// overflows, the allocation error handler when the allocator fails.
79fn infallible<T>(res: AllocResult<T>) -> T {
80    match res {
81        Ok(value) => value,
82        Err(Some(layout)) => alloc::handle_alloc_error(layout),
83        Err(None) => panic!("capacity overflow"),
84    }
85}
86
87/// A raw handle on a storage, which does not count as a reference by itself: this is what
88/// the [`HeapRef`] holding it acquires and releases.
89#[derive(Clone, Copy)]
90#[repr(transparent)]
91struct Heap(NonNull<HeapHeader>);
92
93/// A header aligned like the storages that are allocated, so that its (empty) data is too.
94#[repr(C, align(8))]
95struct EmptyHeapHeader(HeapHeader);
96
97/// The storage of whatever holds no values at all, which is never allocated nor freed: it
98/// is not counted, see [`Heap::is_immortal`], and is never written since it has no
99/// octets, and nothing is ever attached to it.
100static EMPTY_HEAP_HEADER: EmptyHeapHeader = EmptyHeapHeader(HeapHeader {
101    count: AtomicUsize::new(usize::MAX),
102    cap: 0,
103    side: AtomicPtr::new(ptr::null_mut()),
104});
105
106impl Heap {
107
108    /// A handle on the storage of whatever holds no values at all.
109    // SAFETY: A static is never null.
110    const EMPTY: Self = Self(unsafe { NonNull::new_unchecked((&raw const EMPTY_HEAP_HEADER.0).cast_mut()) });
111
112    /// Whether this is the storage of whatever holds no values at all, which is not counted.
113    #[inline]
114    fn is_immortal(self) -> bool {
115        self.0 == Self::EMPTY.0
116    }
117
118    /// The layout of a storage of that capacity, in units of 8 octets, absent if it
119    /// overflows.
120    fn layout(cap: usize) -> Option<Layout> {
121        cap.checked_mul(ALIGN)
122            .and_then(|size| size.checked_add(mem::size_of::<HeapHeader>()))
123            .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
124    }
125
126    /// Allocate a storage holding at least that many octets, all zeroes, its only reference
127    /// being the returned handle. A storage is always zeroed when allocated, and so is what
128    /// it grows by, see [`Self::grow`]: its whole capacity is always initialized, and
129    /// zeroes need not be written where it was never written.
130    fn alloc(len: usize) -> AllocResult<Self> {
131        let cap = len.div_ceil(ALIGN);
132        let layout = Self::layout(cap).ok_or(None)?;
133        // SAFETY: The layout is never zero-sized, it always holds the header.
134        let ptr = unsafe { alloc::alloc_zeroed(layout) };
135        let ptr = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(layout))?;
136        // SAFETY: The allocation is valid for the header.
137        unsafe { ptr.write(HeapHeader { count: AtomicUsize::new(1), cap, side: AtomicPtr::new(ptr::null_mut()) }) };
138        Ok(Self(ptr))
139    }
140
141    /// The data of this storage.
142    #[inline]
143    fn data(self) -> *mut u8 {
144        // SAFETY: The data directly follows the header, in the same allocation.
145        unsafe { self.0.as_ptr().add(1).cast::<u8>() }
146    }
147
148    /// The capacity of the data of this storage, in octets.
149    #[inline]
150    fn capacity(self) -> usize {
151        // SAFETY: The handle points to a live storage.
152        unsafe { (*self.0.as_ptr()).cap * ALIGN }
153    }
154
155    #[inline]
156    fn header(&self) -> &HeapHeader {
157        // SAFETY: The handle points to a live storage.
158        unsafe { self.0.as_ref() }
159    }
160
161    /// Whether this is the only reference to the storage, which is what allows writing to
162    /// it, the acquire ordering making the writes of the released references visible.
163    #[inline]
164    fn is_unique(self) -> bool {
165        self.header().count.load(Ordering::Acquire) == 1
166    }
167
168    /// Add a reference to this storage.
169    #[inline]
170    fn acquire(self) {
171        if self.is_immortal() {
172            return;
173        }
174        let old = self.header().count.fetch_add(1, Ordering::Relaxed);
175        // Like `Arc`, never let the count overflow, which would free a live storage.
176        if old > isize::MAX as usize {
177            std::process::abort();
178        }
179    }
180
181    /// Release a reference to this storage, freeing it with its side allocations if it
182    /// was the last one.
183    ///
184    /// # Safety
185    ///
186    /// The caller has to own the reference it releases, and not use the handle anymore.
187    #[inline]
188    unsafe fn release(self) {
189        if self.is_immortal() || self.header().count.fetch_sub(1, Ordering::Release) != 1 {
190            return;
191        }
192        atomic::fence(Ordering::Acquire);
193        // SAFETY: This was the last reference, nothing else can reach the storage.
194        unsafe { self.free() }
195    }
196
197    #[cold]
198    unsafe fn free(self) {
199        let header = self.0.as_ptr();
200        // SAFETY: The storage is ours alone, allocated with that layout.
201        unsafe {
202            self.free_sides();
203            alloc::dealloc(header.cast(), Self::layout((*header).cap).unwrap_unchecked());
204        }
205    }
206
207    /// The layout of a side allocation of that payload size, absent if it overflows.
208    fn side_layout(size: usize) -> Option<Layout> {
209        size.checked_add(mem::size_of::<SideHeader>())
210            .and_then(|size| Layout::from_size_align(size, ALIGN).ok())
211    }
212
213    /// Attach that side allocation to this storage, which frees it with itself.
214    ///
215    /// The storage may already be shared, hence the lock-free push, but nothing reads the
216    /// list of side allocations before the last reference frees it.
217    fn push_side(self, side: DetachedSide) {
218        debug_assert!(!self.is_immortal(), "nothing is attached to the empty storage");
219        let side = ManuallyDrop::new(side).0;
220        let head = &self.header().side;
221        let mut next = head.load(Ordering::Relaxed);
222        loop {
223            // SAFETY: The side allocation is ours until it is pushed.
224            unsafe { (*side.as_ptr()).next = next };
225            match head.compare_exchange_weak(next, side.as_ptr(), Ordering::Release, Ordering::Relaxed) {
226                Ok(_) => break,
227                Err(current) => next = current,
228            }
229        }
230    }
231
232    /// Free the side allocations of this storage, which nothing uses anymore once it is
233    /// the only reference to the storage.
234    ///
235    /// # Safety
236    ///
237    /// The caller has to own the only reference to the storage.
238    unsafe fn free_sides(self) {
239        let mut side = self.header().side.swap(ptr::null_mut(), Ordering::Relaxed);
240        while !side.is_null() {
241            // SAFETY: The side allocations are ours alone, and were allocated with the
242            // layout their header gives back.
243            unsafe {
244                let next = (*side).next;
245                alloc::dealloc(side.cast(), Self::side_layout((*side).size).unwrap_unchecked());
246                side = next;
247            }
248        }
249    }
250
251    /// Grow this storage to a capacity of at least that many octets, at least doubling it,
252    /// the octets it adds being zeroed. This may move the storage, hence the handle being
253    /// updated, and its side allocations with it.
254    ///
255    /// # Safety
256    ///
257    /// The caller has to own the only reference to the storage.
258    ///
259    /// When the allocation fails, the storage is left as it was.
260    #[cold]
261    unsafe fn grow(&mut self, capacity: usize) -> AllocResult<()> {
262        let old_cap = self.header().cap;
263        let cap = capacity.div_ceil(ALIGN).max(old_cap * 2);
264        // SAFETY: The layout of a live storage is valid.
265        let old_layout = unsafe { Self::layout(old_cap).unwrap_unchecked() };
266        let new_layout = Self::layout(cap).ok_or(None)?;
267        // SAFETY: The storage is ours alone, allocated with that layout.
268        let ptr = unsafe { alloc::realloc(self.0.as_ptr().cast(), old_layout, new_layout.size()) };
269        self.0 = NonNull::new(ptr.cast::<HeapHeader>()).ok_or(Some(new_layout))?;
270        // SAFETY: The new allocation holds the header, followed by that many units.
271        unsafe {
272            (*self.0.as_ptr()).cap = cap;
273            self.data().add(old_cap * ALIGN).write_bytes(0, (cap - old_cap) * ALIGN);
274        }
275        Ok(())
276    }
277
278}
279
280/// A side allocation that is not attached to a storage yet, see [`Heap::push_side`],
281/// which is freed if it never is: its payload is filled before the allocation is attached,
282/// so that nothing is left attached to a shared storage when filling it fails.
283struct DetachedSide(NonNull<SideHeader>);
284
285impl DetachedSide {
286
287    /// Allocate a side allocation of that payload size, whose payload is left
288    /// uninitialized and aligned on 8 octets.
289    fn new(size: usize) -> AllocResult<Self> {
290        let layout = Heap::side_layout(size).ok_or(None)?;
291        // SAFETY: The layout is never zero-sized, it always holds the side header.
292        let side = NonNull::new(unsafe { alloc::alloc(layout) }.cast::<SideHeader>()).ok_or(Some(layout))?;
293        // SAFETY: The allocation is valid for the side header.
294        unsafe { side.write(SideHeader { next: ptr::null_mut(), size }) };
295        Ok(Self(side))
296    }
297
298    /// The payload of this side allocation.
299    #[inline]
300    fn payload(&self) -> NonNull<u8> {
301        // SAFETY: The payload directly follows the side header, in the same allocation.
302        unsafe { self.0.add(1).cast::<u8>() }
303    }
304
305}
306
307impl Drop for DetachedSide {
308    fn drop(&mut self) {
309        // SAFETY: The side allocation was never attached, and was allocated with the layout
310        // its header gives back.
311        unsafe { alloc::dealloc(self.0.as_ptr().cast(), Heap::side_layout((*self.0.as_ptr()).size).unwrap_unchecked()) }
312    }
313}
314
315/// A reference to a storage, and where in it: what a [`Buf`] is made of, unless it is held
316/// in place.
317struct HeapRef {
318    /// Inner pointer to the heap.
319    inner: Heap,
320    /// Offset in the storage, in octets.
321    offset: usize,
322}
323
324impl HeapRef {
325
326    /// A reference to the storage of whatever holds no values at all.
327    const EMPTY: Self = Self {
328        inner: Heap::EMPTY,
329        offset: 0,
330    };
331
332    /// A reference to a new storage of a copy of these octets, of at least that capacity.
333    fn copy(bytes: &[u8], capacity: usize) -> AllocResult<Self> {
334        let storage = Heap::alloc(bytes.len().max(capacity))?;
335        // SAFETY: The storage holds at least that many octets.
336        unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), storage.data(), bytes.len()) };
337        Ok(Self { inner: storage, offset: 0 })
338    }
339
340    /// Where these octets start in the storage.
341    #[inline]
342    fn ptr(&self) -> *mut u8 {
343        // SAFETY: The offset is within the storage.
344        unsafe { self.inner.data().add(self.offset) }
345    }
346
347    /// Another reference to the same storage, that many octets further.
348    #[inline]
349    fn clone_at(&self, count: usize) -> Self {
350        self.inner.acquire();
351        Self { inner: self.inner, offset: self.offset + count }
352    }
353
354    #[inline]
355    fn is_unique(&self) -> bool {
356        self.inner.is_unique()
357    }
358
359    /// Whether what holds this reference can be a [`BufMut`]: when it is the only reference
360    /// to its storage, or when this is the empty storage, which a buffer never writes but
361    /// grows out of, see [`BufMut::reserve`].
362    #[inline]
363    fn is_writable(&self) -> bool {
364        self.inner.is_immortal() || self.inner.is_unique()
365    }
366
367}
368
369impl Clone for HeapRef {
370    #[inline]
371    fn clone(&self) -> Self {
372        self.clone_at(0)
373    }
374}
375
376impl Drop for HeapRef {
377    #[inline]
378    fn drop(&mut self) {
379        // SAFETY: This owns its reference, and is not used anymore.
380        unsafe { self.inner.release() }
381    }
382}
383
384
385// =========================== //
386//            Spans            //
387// =========================== //
388
389/// Where the values of a [`Buf`] are in its storage: the range of octets of each of them,
390/// either computed, see [`PackedSpans`], or given by a table, see [`TableSpans`].
391///
392/// # Safety
393///
394/// The ranges must be those the buffer was built with.
395pub unsafe trait Spans: Copy + Send + Sync + 'static {
396
397    /// The spans of no values at all.
398    const EMPTY: Self;
399
400    /// The offset and the length, in octets, of the value at that index, relative to where
401    /// the buffer starts in its storage.
402    ///
403    /// # Safety
404    ///
405    /// The buffer these are the spans of must hold a value at that index.
406    unsafe fn span(self, index: usize) -> (usize, usize);
407
408    /// How many octets further the buffer starts, and the spans, of the buffer starting
409    /// that many values further, which is what slicing is made of.
410    ///
411    /// # Safety
412    ///
413    /// The buffer these are the spans of must hold at least that many values.
414    unsafe fn advance(self, count: usize) -> (usize, Self);
415
416}
417
418/// The spans of values packed one after the other, each as many octets as their type:
419/// nothing is stored, the range of a value is computed from its index.
420pub struct PackedSpans<T>(PhantomData<fn() -> T>);
421
422impl<T> PackedSpans<T> {
423    #[inline]
424    const fn new() -> Self {
425        Self(PhantomData)
426    }
427}
428
429impl<T> Clone for PackedSpans<T> {
430    #[inline]
431    fn clone(&self) -> Self {
432        *self
433    }
434}
435
436impl<T> Copy for PackedSpans<T> {}
437
438// SAFETY: The ranges are those of packed values of that type.
439unsafe impl<T: 'static> Spans for PackedSpans<T> {
440
441    const EMPTY: Self = Self::new();
442
443    #[inline]
444    unsafe fn span(self, index: usize) -> (usize, usize) {
445        (index * mem::size_of::<T>(), mem::size_of::<T>())
446    }
447
448    #[inline]
449    unsafe fn advance(self, count: usize) -> (usize, Self) {
450        (count * mem::size_of::<T>(), self)
451    }
452
453}
454
455/// The spans of values anywhere in the storage, each given by a table of ranges of octets,
456/// relative to where the buffer starts: the table is a side allocation of the storage, so
457/// it lives as long as the storage without being counted, and slicing the values only
458/// moves the pointer to their ranges.
459///
460/// The span of a buffer built with a single value takes no table: the buffer starts where
461/// its value does, and the length of the value is held in place of the pointer, tagged by
462/// its lowest bit, which a table, aligned for its ranges, never has set.
463#[derive(Clone, Copy)]
464pub struct TableSpans(NonNull<Range<u32>>);
465
466// SAFETY: The table is never written once it is shared.
467unsafe impl Send for TableSpans {}
468unsafe impl Sync for TableSpans {}
469
470impl TableSpans {
471
472    /// The span of a single value of that length, starting where the buffer starts, which
473    /// is never more than `isize::MAX` octets since it is within an allocation.
474    #[inline]
475    fn single(len: usize) -> Self {
476        debug_assert!(len <= isize::MAX as usize);
477        // SAFETY: The tag bit is set, so the address is never zero.
478        Self(NonNull::without_provenance(unsafe { NonZero::new_unchecked(len << 1 | 1) }))
479    }
480
481    /// The length of the single value these are the span of, absent for a table.
482    #[inline]
483    fn single_len(self) -> Option<usize> {
484        let addr = self.0.addr().get();
485        (addr & 1 != 0).then_some(addr >> 1)
486    }
487
488}
489
490// SAFETY: The ranges are those of the table, checked when it was built, or the single one
491// starting where the buffer does.
492unsafe impl Spans for TableSpans {
493
494    const EMPTY: Self = Self(NonNull::dangling());
495
496    #[inline]
497    unsafe fn span(self, index: usize) -> (usize, usize) {
498        if let Some(len) = self.single_len() {
499            return (0, len);
500        }
501        // SAFETY: The caller guarantees the range is there, and it was checked not to be
502        // inverted when the table was built.
503        let Range { start, end } = unsafe { self.0.add(index).read() };
504        (start as usize, (end - start) as usize)
505    }
506
507    #[inline]
508    unsafe fn advance(self, count: usize) -> (usize, Self) {
509        if let Some(len) = self.single_len() {
510            // The caller guarantees there is that many values, so none or the only one.
511            return if count == 0 { (0, self) } else { (len, Self::EMPTY) };
512        }
513        // SAFETY: The caller guarantees there are that many spans.
514        (0, Self(unsafe { self.0.add(count) }))
515    }
516
517}
518
519
520// =========================== //
521//           Elements          //
522// =========================== //
523
524/// A type of the values a [`Buf`] holds: where they are in its storage, see [`Spans`], and
525/// what octets are one of them.
526///
527/// This is implemented for every [`PackedElement`], and for [`str`](prim@str), whose values are at
528/// the spans of a table.
529///
530/// # Safety
531///
532/// [`Self::read`] must be sound for any octets [`Self::validate`] accepts.
533pub unsafe trait Element: Send + Sync + 'static {
534
535    /// How one value is given out: by value for a packed type, borrowed for a string.
536    type Ref<'a>: Copy + Debug;
537
538    /// Where the values are in the storage.
539    type Spans: Spans;
540
541    /// Whether a scalar of this type is held in place of a storage, which only a packed
542    /// type small enough can be.
543    const INLINE_FIXED: bool;
544
545    /// Whether these octets are one valid value.
546    fn validate(bytes: &[u8]) -> bool;
547
548    /// The value in these octets.
549    ///
550    /// # Safety
551    ///
552    /// The octets must have been accepted by [`Self::validate`], and be aligned for a
553    /// packed type.
554    unsafe fn read<'a>(ptr: *const u8, len: usize) -> Self::Ref<'a>
555    where
556        Self: 'a;
557
558    /// Format the values of one row of a buffer for [`Debug`], along its first dimension,
559    /// within the brackets of that row: separated by commas unless a type has a better way.
560    fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
561    where
562        I: Iterator<Item = Self::Ref<'a>>,
563        Self: 'a,
564    {
565        for (index, value) in values.enumerate() {
566            if index != 0 {
567                f.write_str(", ")?;
568            }
569            Debug::fmt(&value, f)?;
570        }
571        Ok(())
572    }
573
574}
575
576/// An element whose values are packed as their octets, one after the other, which is what
577/// allows a [`Buf`] of them to be seen as a slice, see [`Buf::as_slice`], and written, see
578/// [`BufMut`].
579///
580/// # Safety
581///
582/// The type must have no padding and not be zero-sized, its values must be exactly the
583/// octets [`Self::validate_all`] accepts, read as they are, and octets that are all zeroes
584/// must be a valid value, which is what new room in a storage holds.
585pub unsafe trait PackedElement: Element<Spans = PackedSpans<Self>> + Copy {
586
587    /// Whether the octets of a whole number of consecutive values are all valid values,
588    /// in a single pass: what octets are checked with when they are cast, and what
589    /// [`Element::validate`] is for one value.
590    fn validate_all(bytes: &[u8]) -> bool;
591
592}
593
594/// What [`Element::INLINE_FIXED`] is for a packed type, checking it can be held in place.
595const fn inline_fixed<T>() -> bool {
596    assert!(mem::size_of::<T>() > 0, "a packed type is not zero-sized");
597    assert!(mem::size_of::<T>() <= mem::size_of::<Repr>(), "a packed type fits in place of a storage");
598    assert!(mem::align_of::<T>() <= ALIGN, "a packed type is aligned on at most 8 octets");
599    true
600}
601
602/// Implement [`PackedElement`] for these types, all of whose octet patterns are valid
603/// values unless a check of each octet is given.
604macro_rules! impl_packed_element {
605    ($($ty:ty $(where |$octet:ident| $valid:expr)? $(, debug $debug:path)?);* $(;)?) => { $(
606        // SAFETY: The type has no padding, and is read from the octets validated.
607        unsafe impl Element for $ty {
608
609            type Ref<'a> = $ty;
610            type Spans = PackedSpans<$ty>;
611
612            const INLINE_FIXED: bool = inline_fixed::<$ty>();
613
614            #[inline]
615            fn validate(bytes: &[u8]) -> bool {
616                bytes.len() == mem::size_of::<$ty>() && Self::validate_all(bytes)
617            }
618
619            #[inline]
620            unsafe fn read<'a>(ptr: *const u8, _len: usize) -> $ty
621            where
622                $ty: 'a,
623            {
624                // SAFETY: The caller guarantees the value is there, and aligned.
625                unsafe { ptr.cast::<$ty>().read() }
626            }
627
628            $(
629            #[inline]
630            fn fmt_row<'a, I>(values: I, f: &mut fmt::Formatter<'_>) -> fmt::Result
631            where
632                I: Iterator<Item = $ty>,
633                $ty: 'a,
634            {
635                $debug(values, f)
636            }
637            )?
638
639        }
640
641        // SAFETY: Same as above, and zero is a valid value of each of these types.
642        unsafe impl PackedElement for $ty {
643            #[inline]
644            fn validate_all(_bytes: &[u8]) -> bool {
645                true $(&& _bytes.iter().all(|&$octet| $valid))?
646            }
647        }
648    )* };
649}
650
651impl_packed_element!(
652    u8, debug fmt_octets;
653    i8; u16; i16; u32; i32; u64; i64; f32; f64; DevEnum;
654    bool where |octet| octet <= 1;
655    DevState where |octet| octet <= DevState::Unknown as u8;
656);
657
658/// Format octets as hexadecimal for [`Debug`], with runs of readable ASCII quoted, which is
659/// how the octets of a stream are best told apart.
660fn fmt_octets(octets: impl Iterator<Item = u8>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
661
662    let mut ascii = false;
663
664    for (index, byte) in octets.enumerate() {
665
666        if index != 0 && !ascii {
667            f.write_str(" ")?;
668        }
669
670        if byte.is_ascii_alphanumeric() || matches!(byte, b' ' | b':' | b'/' | b'.' | b'-' | b'_') {
671            if !ascii {
672                f.write_str("'")?;
673                ascii = true;
674            }
675            write!(f, "{}", byte as char)?;
676        } else {
677            if ascii {
678                f.write_str("' ")?;
679                ascii = false;
680            }
681            write!(f, "{byte:02X}")?;
682        }
683
684    }
685
686    if ascii {
687        f.write_str("'")?;
688    }
689
690    Ok(())
691
692}
693
694/// Format the octets of packed values as hexadecimal, two digits each, in the order they
695/// are stored. The octets of each value are grouped together, groups being separated by a
696/// space, except for octets, which are a single run that [`BufMut::from_hex`] parses back.
697fn fmt_hex<T: PackedElement>(octets: &[u8], f: &mut fmt::Formatter<'_>, upper: bool) -> fmt::Result {
698    let size = mem::size_of::<T>();
699    for (index, &byte) in octets.iter().enumerate() {
700        if size > 1 && index != 0 && index % size == 0 {
701            f.write_str(" ")?;
702        }
703        if upper { write!(f, "{byte:02X}")? } else { write!(f, "{byte:02x}")? }
704    }
705    Ok(())
706}
707
708// SAFETY: A string is read from octets that are valid UTF-8.
709unsafe impl Element for str {
710
711    type Ref<'a> = &'a str;
712    type Spans = TableSpans;
713
714    const INLINE_FIXED: bool = false;
715
716    #[inline]
717    fn validate(bytes: &[u8]) -> bool {
718        str::from_utf8(bytes).is_ok()
719    }
720
721    #[inline]
722    unsafe fn read<'a>(ptr: *const u8, len: usize) -> &'a str
723    where
724        str: 'a,
725    {
726        // SAFETY: The caller guarantees the octets are there, and valid UTF-8.
727        unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) }
728    }
729
730}
731
732
733// =========================== //
734//           Buffers           //
735// =========================== //
736
737/// Either a reference to the storage of a buffer, or a scalar held in place, which of the
738/// two being known from the type of the buffer, see [`Buf::INLINE`].
739#[repr(C)]
740union Repr {
741    raw: ManuallyDrop<HeapRef>,
742    inline: [MaybeUninit<u64>; mem::size_of::<HeapRef>() / 8],
743}
744
745/// A shared, typed, N-dimensional array of values, in column-major order, a scalar for
746/// `DIM == 0`. Its dimensions are fixed once it is built. Octets are a `Buf<u8, 1>`, cast to other packed types with [`Self::cast`], and
747/// turned into strings with [`Buf::from_spans`].
748///
749/// Cloning a buffer only counts one more reference to its storage, and so does slicing it,
750/// which is what allows the buffer of a received message to be handed out in pieces without
751/// copying any of it. A packed scalar is held in place and has no storage.
752pub struct Buf<T: Element + ?Sized, const DIM: usize> {
753    repr: Repr,
754    spans: T::Spans,
755    dim: [usize; DIM],
756    _t: PhantomData<*const T>,
757}
758
759// SAFETY: The storage is only written through a unique reference, see `BufMut`, and the
760// side allocations are never written once shared; the elements are `Send + Sync`.
761unsafe impl<T: Element + ?Sized, const DIM: usize> Send for Buf<T, DIM> {}
762unsafe impl<T: Element + ?Sized, const DIM: usize> Sync for Buf<T, DIM> {}
763
764/// The number of values of an array of those dimensions, absent if it overflows.
765#[inline]
766fn checked_len(dim: &[usize]) -> Option<usize> {
767    dim.iter().try_fold(1usize, |len, &d| len.checked_mul(d))
768}
769
770/// The bounds of that range over a length, panicking like slice indexing does.
771#[track_caller]
772fn range_bounds<R: RangeBounds<usize>>(range: R, len: usize) -> Range<usize> {
773    let start = match range.start_bound() {
774        Bound::Included(&start) => start,
775        Bound::Excluded(&start) => start.checked_add(1).expect("range start overflow"),
776        Bound::Unbounded => 0,
777    };
778    let end = match range.end_bound() {
779        Bound::Included(&end) => end.checked_add(1).expect("range end overflow"),
780        Bound::Excluded(&end) => end,
781        Bound::Unbounded => len,
782    };
783    assert!(start <= end, "slice index starts at {start} but ends at {end}");
784    assert!(end <= len, "range end index {end} out of range for length {len}");
785    start..end
786}
787
788
789impl<T: Element + ?Sized, const DIM: usize> Buf<T, DIM> {
790
791    /// Whether the buffer is held in place rather than in a storage, which only a scalar of
792    /// a packed type is, and which is known from its type alone.
793    const INLINE: bool = DIM == 0 && T::INLINE_FIXED;
794
795    /// A buffer of no values, all its dimensions being zero, which allocates nothing: every
796    /// empty buffer shares the same static storage.
797    #[inline]
798    pub const fn new() -> Self {
799        const { assert!(DIM >= 1, "a scalar always holds one value") };
800        let raw = ManuallyDrop::new(HeapRef::EMPTY);
801        Self {
802            repr: Repr { raw },
803            spans: T::Spans::EMPTY,
804            dim: [0; DIM],
805            _t: PhantomData,
806        }
807    }
808
809    /// A buffer of the values at that reference to a storage.
810    ///
811    /// # Safety
812    ///
813    /// The buffer must not be inline, and the storage must hold its values there, with
814    /// those spans, aligned for a packed type.
815    #[inline]
816    unsafe fn from_raw(raw: HeapRef, spans: T::Spans, dim: [usize; DIM]) -> Self {
817        debug_assert!(!Self::INLINE);
818        Self {
819            repr: Repr { raw: ManuallyDrop::new(raw) },
820            spans,
821            dim,
822            _t: PhantomData,
823        }
824    }
825
826    /// The reference to the storage of this buffer, which must not be inline.
827    #[inline]
828    fn raw(&self) -> &HeapRef {
829        debug_assert!(!Self::INLINE);
830        // SAFETY: A buffer that is not inline always holds a reference to its storage.
831        unsafe { &self.repr.raw }
832    }
833
834    /// [`Self::raw`], writable, for a buffer that changes its storage or where in it it is.
835    #[inline]
836    fn raw_mut(&mut self) -> &mut HeapRef {
837        debug_assert!(!Self::INLINE);
838        // SAFETY: A buffer that is not inline always holds a reference to its storage.
839        unsafe { &mut self.repr.raw }
840    }
841
842    /// The reference to the storage of this buffer, which must not be inline, moved out of
843    /// it.
844    #[inline]
845    fn into_raw(self) -> HeapRef {
846        let this = ManuallyDrop::new(self);
847        // SAFETY: The reference is moved out of a buffer that is never dropped.
848        unsafe { ptr::read(this.raw()) }
849    }
850
851    /// Where the values of this buffer start, which its spans are relative to.
852    #[inline]
853    fn base(&self) -> *const u8 {
854        if Self::INLINE {
855            ptr::addr_of!(self.repr).cast::<u8>()
856        } else {
857            self.raw().ptr()
858        }
859    }
860
861    /// [`Self::base`], writable: a scalar held in place is only writable through a pointer
862    /// taken from an exclusive reference.
863    #[inline]
864    fn base_mut(&mut self) -> *mut u8 {
865        if Self::INLINE {
866            ptr::addr_of_mut!(self.repr).cast::<u8>()
867        } else {
868            self.raw().ptr()
869        }
870    }
871
872    /// The value at that index.
873    ///
874    /// # Safety
875    ///
876    /// The index must be below the length.
877    #[inline]
878    unsafe fn read(&self, index: usize) -> T::Ref<'_> {
879        // SAFETY: The spans give the range of a value this buffer holds, validated.
880        unsafe {
881            let (offset, len) = self.spans.span(index);
882            T::read(self.base().add(offset), len)
883        }
884    }
885
886    /// The dimensions of this buffer, the first one varying the fastest.
887    #[inline]
888    pub fn dim(&self) -> [usize; DIM] {
889        self.dim
890    }
891
892    /// The number of values of this buffer, 1 for a scalar.
893    #[inline]
894    pub fn len(&self) -> usize {
895        self.dim.iter().product()
896    }
897
898    #[inline]
899    pub fn is_empty(&self) -> bool {
900        self.len() == 0
901    }
902
903    /// The index among the values of this buffer of the value at that position, one
904    /// coordinate per dimension, in column-major order: the first coordinate is the one
905    /// varying the fastest. Absent if a coordinate is out of its dimension.
906    #[inline]
907    pub fn raw_index(&self, pos: [usize; DIM]) -> Option<usize> {
908        let mut index = 0;
909        let mut stride = 1;
910        for (&coord, &dim) in pos.iter().zip(&self.dim) {
911            if coord >= dim {
912                return None;
913            }
914            index += coord * stride;
915            stride *= dim;
916        }
917        Some(index)
918    }
919
920    /// The value at that position, one coordinate per dimension, `[x]` for one and `[x, y]`
921    /// for two, `[]` giving the value of a scalar. Absent if a coordinate is
922    /// out of its dimension.
923    #[inline]
924    pub fn get(&self, pos: [usize; DIM]) -> Option<T::Ref<'_>> {
925        let index = self.raw_index(pos)?;
926        // SAFETY: The index of a position within the dimensions is below the length.
927        Some(unsafe { self.read(index) })
928    }
929
930    /// The value at that position as a scalar of its own, see [`Self::get`]: copied in
931    /// place for a packed type, sharing the storage for a string. Absent if a coordinate
932    /// is out of its dimension.
933    pub fn get_scalar(&self, pos: [usize; DIM]) -> Option<Buf<T, 0>> {
934
935        let index = self.raw_index(pos)?;
936
937        if Buf::<T, 0>::INLINE {
938            let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
939            // SAFETY: The index is within the buffer, and a packed value fits in place, see
940            // `inline_fixed`; the spans of packed values are the same wherever they are.
941            unsafe {
942                let (offset, len) = self.spans.span(index);
943                ptr::copy_nonoverlapping(self.base().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
944            }
945            Some(Buf { repr, spans: self.spans, dim: [], _t: PhantomData })
946        } else {
947            // SAFETY: The index is within the buffer, and a type that is not held in place
948            // as a scalar is not held in place here either; the value starts whole values
949            // further, so it is aligned.
950            unsafe {
951                let (octets, spans) = self.spans.advance(index);
952                Some(Buf::from_raw(self.raw().clone_at(octets), spans, []))
953            }
954        }
955
956    }
957
958    /// The value at that index among the values of this buffer, in column-major order, see
959    /// [`Self::raw_index`]. Absent if the index is out of the length.
960    #[inline]
961    pub fn get_raw(&self, index: usize) -> Option<T::Ref<'_>> {
962        // SAFETY: The index is checked against the length.
963        (index < self.len()).then(|| unsafe { self.read(index) })
964    }
965
966    /// The values of this buffer, in column-major order.
967    #[inline]
968    pub fn iter(&self) -> impl ExactSizeIterator<Item = T::Ref<'_>> + '_ {
969        // SAFETY: The indices are all below the length.
970        (0..self.len()).map(move |index| unsafe { self.read(index) })
971    }
972
973    /// The part of this buffer within that range of its last dimension, which is the
974    /// slowest varying one, so that the part shares the same storage: a range of values for
975    /// one dimension, a range of rows for two.
976    ///
977    /// # Panics
978    ///
979    /// If the range is out of the last dimension, like slice indexing.
980    #[track_caller]
981    pub fn slice<R: RangeBounds<usize>>(&self, range: R) -> Self {
982
983        const { assert!(DIM >= 1, "a scalar cannot be sliced") };
984        let Range { start, end } = range_bounds(range, self.dim[DIM - 1]);
985
986        let stride: usize = self.dim[..DIM - 1].iter().product();
987        
988        // SAFETY: The range is within the buffer.
989        let (octets, spans) = unsafe { self.spans.advance(start * stride) };
990        let mut dim = self.dim;
991        dim[DIM - 1] = end - start;
992
993        // SAFETY: The storage holds the values of the part there, aligned since they are
994        // whole values further.
995        unsafe { Self::from_raw(self.raw().clone_at(octets), spans, dim) }
996
997    }
998
999    /// Take the part of this buffer before `at` along its last dimension out as a buffer
1000    /// of its own, this one keeping the part from `at` on, both sharing the storage: how a
1001    /// message is framed out of the octets that arrived, the ones behind it being the
1002    /// front of the next ones.
1003    ///
1004    /// # Panics
1005    ///
1006    /// If `at` is past the last dimension.
1007    #[track_caller]
1008    pub fn split_to(&mut self, at: usize) -> Self {
1009        let front = self.slice(..at);
1010        *self = self.slice(at..);
1011        front
1012    }
1013
1014    /// Take the part of this buffer from `at` on along its last dimension out as a buffer
1015    /// of its own, this one keeping the part before `at`, both sharing the storage.
1016    ///
1017    /// # Panics
1018    ///
1019    /// If `at` is past the last dimension.
1020    #[track_caller]
1021    pub fn split_off(&mut self, at: usize) -> Self {
1022        let back = self.slice(at..);
1023        *self = self.slice(..at);
1024        back
1025    }
1026
1027    /// The same values with other dimensions, as long as they are as many: typically values
1028    /// decoded in one dimension and given the two dimensions they actually have. A scalar is
1029    /// one value, so it is reshaped to and from any dimensions of one value, being copied
1030    /// in or out of place for a packed type, see [`Buf`].
1031    pub fn reshape<const D: usize>(self, dim: [usize; D]) -> Option<Buf<T, D>> {
1032        if checked_len(&dim)? != self.len() {
1033            return None;
1034        }
1035        let spans = self.spans;
1036        // SAFETY: In every case, the values are kept with their spans, and are as many.
1037        Some(match (Self::INLINE, Buf::<T, D>::INLINE) {
1038            (false, false) => unsafe { Buf::from_raw(self.into_raw(), spans, dim) },
1039            // SAFETY: A buffer held in place always holds its inline octets.
1040            (true, true) => Buf { repr: Repr { inline: unsafe { self.repr.inline } }, spans, dim, _t: PhantomData },
1041            (true, false) => unsafe {
1042                let (offset, len) = spans.span(0);
1043                let bytes = slice::from_raw_parts(self.base().add(offset), len);
1044                Buf::from_raw(infallible(HeapRef::copy(bytes, len)), spans, dim)
1045            },
1046            (false, true) => {
1047                let raw = self.into_raw();
1048                let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1049                // SAFETY: The value is copied in place, which is large enough, see
1050                // `inline_fixed`, before the reference is released.
1051                unsafe {
1052                    let (offset, len) = spans.span(0);
1053                    ptr::copy_nonoverlapping(raw.ptr().add(offset), ptr::addr_of_mut!(repr).cast::<u8>(), len);
1054                }
1055                Buf { repr, spans, dim, _t: PhantomData }
1056            }
1057        })
1058    }
1059
1060    /// The single value of this buffer as a scalar, absent if it does not hold exactly one:
1061    /// typically a scalar decoded as one dimension of one, see [`Self::reshape`].
1062    #[inline]
1063    pub fn into_scalar(self) -> Option<Buf<T, 0>> {
1064        self.reshape([])
1065    }
1066
1067    /// Whether this buffer is the only reference to its storage, which a buffer held in
1068    /// place always is.
1069    #[inline]
1070    pub fn is_unique(&self) -> bool {
1071        Self::INLINE || self.raw().is_unique()
1072    }
1073
1074    /// Whether this buffer can be a [`BufMut`], see [`HeapRef::is_writable`].
1075    #[inline]
1076    fn is_writable(&self) -> bool {
1077        Self::INLINE || self.raw().is_writable()
1078    }
1079
1080}
1081
1082impl<T: Element + ?Sized> Buf<T, 1> {
1083
1084    /// Keep only the first values, no more than that many.
1085    #[inline]
1086    pub fn truncate(&mut self, len: usize) {
1087        self.dim[0] = self.dim[0].min(len);
1088    }
1089
1090}
1091
1092impl<T: Element + ?Sized> Buf<T, 0> {
1093
1094    /// The value of this scalar.
1095    #[inline]
1096    pub fn value(&self) -> T::Ref<'_> {
1097        // SAFETY: A scalar always holds one value.
1098        unsafe { self.read(0) }
1099    }
1100
1101}
1102
1103// --- Standard traits impl --- //
1104
1105impl<T: Element + ?Sized, const DIM: usize> Clone for Buf<T, DIM> {
1106    #[inline]
1107    fn clone(&self) -> Self {
1108        let repr = if Self::INLINE {
1109            // SAFETY: A buffer held in place always holds its inline octets.
1110            Repr { inline: unsafe { self.repr.inline } }
1111        } else {
1112            Repr { raw: ManuallyDrop::new(self.raw().clone()) }
1113        };
1114        Self { repr, spans: self.spans, dim: self.dim, _t: PhantomData }
1115    }
1116}
1117
1118impl<T: Element + ?Sized, const DIM: usize> Drop for Buf<T, DIM> {
1119    #[inline]
1120    fn drop(&mut self) {
1121        if !Self::INLINE {
1122            // SAFETY: A buffer that is not inline always holds a reference, not used anymore.
1123            unsafe { ManuallyDrop::drop(&mut self.repr.raw) }
1124        }
1125    }
1126}
1127
1128impl<T: Element + ?Sized, const DIM: usize> Default for Buf<T, DIM> {
1129    /// An empty buffer, see [`Self::new`].
1130    #[inline]
1131    fn default() -> Self {
1132        Self::new()
1133    }
1134}
1135
1136impl<T: Element + ?Sized, const DIM: usize> PartialEq for Buf<T, DIM>
1137where
1138    for<'a> T::Ref<'a>: PartialEq,
1139{
1140    /// Two buffers are equal if they have the same dimensions and values, wherever these
1141    /// are.
1142    fn eq(&self, other: &Self) -> bool {
1143        self.dim == other.dim && self.iter().eq(other.iter())
1144    }
1145}
1146
1147impl<T: Element + ?Sized, const DIM: usize> Eq for Buf<T, DIM>
1148where
1149    for<'a> T::Ref<'a>: Eq,
1150{}
1151
1152// --- Formatters --- //
1153
1154/// Format a buffer for [`Debug`]: its name and dimensions, and its values with one pair of
1155/// brackets per dimension, the first one innermost, `Buf<3, 2>[[1, 2, 3], [4, 5, 6]]`, or
1156/// one row per line in the alternate form. A scalar is its value in parentheses.
1157fn fmt_buf<'a, T, I>(f: &mut fmt::Formatter<'_>, name: &str, dim: &[usize], mut values: I) -> fmt::Result
1158where
1159    T: Element + ?Sized + 'a,
1160    I: Iterator<Item = T::Ref<'a>>,
1161{
1162    f.write_str(name)?;
1163    if dim.is_empty() {
1164        f.write_str("(")?;
1165        T::fmt_row(values, f)?;
1166        return f.write_str(")");
1167    }
1168    f.write_str("<")?;
1169    for (index, d) in dim.iter().enumerate() {
1170        if index != 0 {
1171            f.write_str(", ")?;
1172        }
1173        write!(f, "{d}")?;
1174    }
1175    f.write_str(">")?;
1176    fmt_level::<T, I>(f, dim, 0, &mut values)
1177}
1178
1179/// Format the values within the last of these dimensions, at that depth of nesting.
1180fn fmt_level<'a, T, I>(f: &mut fmt::Formatter<'_>, dim: &[usize], depth: usize, values: &mut I) -> fmt::Result
1181where
1182    T: Element + ?Sized + 'a,
1183    I: Iterator<Item = T::Ref<'a>>,
1184{
1185    const INDENT: usize = 4;
1186    let (&len, inner) = dim.split_last().expect("at least one dimension");
1187    f.write_str("[")?;
1188    if inner.is_empty() {
1189        T::fmt_row(values.by_ref().take(len), f)?;
1190    } else {
1191        let pretty = f.alternate();
1192        for index in 0..len {
1193            if pretty {
1194                write!(f, "\n{:1$}", "", (depth + 1) * INDENT)?;
1195            } else if index != 0 {
1196                f.write_str(", ")?;
1197            }
1198            fmt_level::<T, I>(f, inner, depth + 1, values)?;
1199            if pretty {
1200                f.write_str(",")?;
1201            }
1202        }
1203        if pretty && len != 0 {
1204            write!(f, "\n{:1$}", "", depth * INDENT)?;
1205        }
1206    }
1207    f.write_str("]")
1208}
1209
1210impl<T: Element + ?Sized, const DIM: usize> Debug for Buf<T, DIM> {
1211    /// Its dimensions and values, row by row, see [`Element::fmt_row`].
1212    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1213        fmt_buf::<T, _>(f, "Buf", &self.dim, self.iter())
1214    }
1215}
1216
1217impl<T: PackedElement> UpperHex for Buf<T, 1> {
1218    /// The octets of the values as hexadecimal, in the order they are stored, each value's
1219    /// grouped and separated by a space, octets being a single run that
1220    /// [`BufMut::from_hex`] parses back.
1221    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1222        fmt_hex::<T>(self.as_bytes(), f, true)
1223    }
1224}
1225
1226impl<T: PackedElement> LowerHex for Buf<T, 1> {
1227    /// The octets of the values as hexadecimal, in the order they are stored, each value's
1228    /// grouped and separated by a space, octets being a single run that
1229    /// [`BufMut::from_hex`] parses back.
1230    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1231        fmt_hex::<T>(self.as_bytes(), f, false)
1232    }
1233}
1234
1235// --- Packed --- //
1236
1237impl<T: PackedElement, const DIM: usize> Buf<T, DIM> {
1238
1239    /// Whether these octets are valid values, as many as the dimensions say, absent if
1240    /// not, and then whether a buffer of them can share their storage, being aligned and
1241    /// not held in place.
1242    #[inline]
1243    fn check_packed(bytes: &[u8], dim: [usize; DIM]) -> Option<bool> {
1244        let size = checked_len(&dim)?.checked_mul(mem::size_of::<T>())?;
1245        if bytes.len() != size || !T::validate_all(bytes) {
1246            return None;
1247        }
1248        Some(!Self::INLINE && bytes.as_ptr().addr().is_multiple_of(mem::align_of::<T>()))
1249    }
1250
1251    /// A buffer of a copy of these octets, held in place for a scalar, and allocating
1252    /// nothing if there are none.
1253    ///
1254    /// # Safety
1255    ///
1256    /// The octets must be valid values, as many as the dimensions say.
1257    unsafe fn copy_from_bytes(bytes: &[u8], dim: [usize; DIM]) -> Self {
1258        if Self::INLINE {
1259            let mut repr = Repr { inline: [MaybeUninit::uninit(); _] };
1260            // SAFETY: The inline octets are large enough, see `inline_fixed`.
1261            unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), ptr::addr_of_mut!(repr).cast::<u8>(), bytes.len()) };
1262            Self { repr, spans: PackedSpans::new(), dim, _t: PhantomData }
1263        } else if bytes.is_empty() {
1264            // SAFETY: The empty storage holds no values, as many as the dimensions say.
1265            unsafe { Self::from_raw(HeapRef::EMPTY, PackedSpans::new(), dim) }
1266        } else {
1267            // SAFETY: A new storage is aligned for any packed type.
1268            unsafe { Self::from_raw(infallible(HeapRef::copy(bytes, bytes.len())), PackedSpans::new(), dim) }
1269        }
1270    }
1271
1272    /// A buffer of these values, with those dimensions, copied into a new storage unless it
1273    /// is a scalar, which is held in place. Absent if the values are not as many as the
1274    /// dimensions say.
1275    pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1276        if checked_len(&dim)? != values.len() {
1277            return None;
1278        }
1279        // SAFETY: A packed type has no padding, so its values are all initialized octets.
1280        let bytes = unsafe { slice::from_raw_parts(values.as_ptr().cast::<u8>(), mem::size_of_val(values)) };
1281        // SAFETY: The octets are those of valid values, as many as the dimensions say.
1282        Some(unsafe { Self::copy_from_bytes(bytes, dim) })
1283    }
1284
1285    /// A buffer of zeroes with those dimensions, see [`BufMut::zeroed`].
1286    #[inline]
1287    pub fn zeroed(dim: [usize; DIM]) -> Self {
1288        BufMut::zeroed(dim).freeze()
1289    }
1290
1291    /// Where the values of this buffer start.
1292    #[inline]
1293    pub fn as_ptr(&self) -> *const T {
1294        self.base().cast::<T>()
1295    }
1296
1297    /// The values of this buffer, in column-major order.
1298    #[inline]
1299    pub fn as_slice(&self) -> &[T] {
1300        // SAFETY: The buffer holds that many initialized and aligned values.
1301        unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
1302    }
1303
1304    /// The octets of the values of this buffer, what a backend encodes them from.
1305    #[inline]
1306    pub fn as_bytes(&self) -> &[u8] {
1307        // SAFETY: A packed type has no padding, so its values are all initialized octets.
1308        unsafe { slice::from_raw_parts(self.base(), self.len() * mem::size_of::<T>()) }
1309    }
1310
1311    /// The octets of this buffer as packed values of another type, with those dimensions,
1312    /// sharing its storage if they are aligned for that type, and copied otherwise, or
1313    /// held in place for a scalar. The buffer is given back if it does not hold as many
1314    /// octets as the dimensions say, or holds an invalid value.
1315    ///
1316    /// This is how a backend decodes an array out of the message it received, in native
1317    /// byte order, typically out of a slice of it.
1318    pub fn cast<U: PackedElement, const D: usize>(self, dim: [usize; D]) -> Result<Buf<U, D>, Self> {
1319
1320        let Some(share) = Buf::<U, D>::check_packed(self.as_bytes(), dim) else { 
1321            return Err(self);
1322        };
1323
1324        // SAFETY: Checked above, the storage being shared only if this one has one.
1325        Ok(unsafe {
1326            if share && !Self::INLINE {
1327                Buf::from_raw(self.into_raw(), PackedSpans::new(), dim)
1328            } else {
1329                Buf::copy_from_bytes(self.as_bytes(), dim)
1330            }
1331        })
1332
1333    }
1334
1335    /// The octets of the values of this buffer, a new buffer for a scalar held in place.
1336    pub fn into_bytes(self) -> Buf<u8, 1> {
1337        let len = self.as_bytes().len();
1338        match self.cast([len]) {
1339            Ok(bytes) => bytes,
1340            Err(_) => unreachable!("every octet is a valid one"),
1341        }
1342    }
1343
1344    /// This buffer as a writable one, for as long as it is borrowed, absent if its storage
1345    /// is shared, like `Arc::get_mut`.
1346    #[inline]
1347    pub fn get_mut(&mut self) -> Option<&mut BufMut<T, DIM>> {
1348        // SAFETY: The buffer is the only reference to its storage, and nothing can share
1349        // it while it is exclusively borrowed.
1350        self.is_writable().then(|| unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() })
1351    }
1352
1353    /// This buffer as a writable one, for as long as it is borrowed, which first copies its
1354    /// values into a storage of their own if its storage is shared: only these values are
1355    /// copied, not the whole storage.
1356    #[inline]
1357    pub fn make_mut(&mut self) -> &mut BufMut<T, DIM> {
1358        if !self.is_writable() {
1359            // SAFETY: The octets are those of the values of this buffer.
1360            *self = unsafe { Self::copy_from_bytes(self.as_bytes(), self.dim) };
1361        }
1362        // SAFETY: The buffer is the only reference to its storage, and borrowed as such.
1363        unsafe { &mut *(self as *mut Self).cast::<BufMut<T, DIM>>() }
1364    }
1365
1366    /// This buffer as one that is statically the only reference to its storage, given
1367    /// back if its storage is shared, which the empty storage never is.
1368    #[inline]
1369    pub fn try_into_mut(self) -> Result<BufMut<T, DIM>, Self> {
1370        if self.is_writable() {
1371            Ok(BufMut(self))
1372        } else {
1373            Err(self)
1374        }
1375    }
1376
1377    /// This buffer as one that is statically the only reference to its storage, which
1378    /// copies its values into a storage of their own if its storage is shared, see
1379    /// [`Self::make_mut`].
1380    #[inline]
1381    pub fn into_mut(mut self) -> BufMut<T, DIM> {
1382        self.make_mut();
1383        BufMut(self)
1384    }
1385
1386    /// The part of this buffer that these values are, sharing its storage, see
1387    /// [`Self::slice`]: what values taken out of [`Self::as_slice`] turn back into, such as
1388    /// the octets a decoder that only handles slices has read.
1389    ///
1390    /// # Panics
1391    ///
1392    /// If the values are not within this buffer, or are not a range of its last dimension:
1393    /// any range of values for one dimension, but only whole rows for two.
1394    #[track_caller]
1395    pub fn slice_ref(&self, subset: &[T]) -> Self {
1396
1397        const { assert!(DIM >= 1, "a scalar cannot be sliced") };
1398        
1399        let size = mem::size_of::<T>();
1400        let offset = subset.as_ptr().addr().wrapping_sub(self.base().addr());
1401        let (start, len) = (offset / size, self.len());
1402        
1403        assert!(offset.is_multiple_of(size) && start <= len && subset.len() <= len - start,
1404            "the values at {:p} are not within the buffer at {:p}, of {len} values", 
1405            subset.as_ptr(), 
1406            self.base());
1407
1408        let stride: usize = self.dim[..DIM - 1].iter().product();
1409        if stride == 0 {
1410            return self.slice(..0);
1411        }
1412
1413        assert!(start.is_multiple_of(stride) && subset.len().is_multiple_of(stride),
1414            "the values {start}..{} are not whole rows of {stride} values", 
1415            start + subset.len());
1416        
1417        self.slice(start / stride..(start + subset.len()) / stride)
1418
1419    }
1420
1421}
1422
1423impl<T: PackedElement> From<T> for Buf<T, 0> {
1424    /// A scalar of that value, held in place.
1425    #[inline]
1426    fn from(value: T) -> Self {
1427        Self::from_slice(slice::from_ref(&value), []).expect("a scalar holds one value")
1428    }
1429}
1430
1431impl<T: PackedElement> From<&[T]> for Buf<T, 1> {
1432    #[inline]
1433    fn from(values: &[T]) -> Self {
1434        Self::from_slice(values, [values.len()]).expect("same length")
1435    }
1436}
1437
1438impl<T: PackedElement> From<Vec<T>> for Buf<T, 1> {
1439    #[inline]
1440    fn from(values: Vec<T>) -> Self {
1441        Self::from(values.as_slice())
1442    }
1443}
1444
1445impl<T: PackedElement> From<Box<[T]>> for Buf<T, 1> {
1446    #[inline]
1447    fn from(values: Box<[T]>) -> Self {
1448        Self::from(&*values)
1449    }
1450}
1451
1452impl<T: PackedElement, const N: usize> From<[T; N]> for Buf<T, 1> {
1453    #[inline]
1454    fn from(values: [T; N]) -> Self {
1455        Self::from(values.as_slice())
1456    }
1457}
1458
1459impl<T: PackedElement, const DIM: usize> From<BufMut<T, DIM>> for Buf<T, DIM> {
1460    #[inline]
1461    fn from(buf: BufMut<T, DIM>) -> Self {
1462        buf.freeze()
1463    }
1464}
1465
1466// --- Table --- //
1467
1468impl<T: Element<Spans = TableSpans> + ?Sized, const DIM: usize> Buf<T, DIM> {
1469
1470    /// The values at these spans of these octets, with those dimensions, sharing their
1471    /// storage, each span being accepted by that check. The octets are given back if the
1472    /// spans are not as many as the dimensions say, if one of them is not accepted, or if
1473    /// their table cannot be allocated, as many spans as the dimensions say being allocated
1474    /// before any is checked, and the dimensions possibly coming off the wire.
1475    fn with_spans<I, F>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM], mut check: F) -> Result<Self, Buf<u8, 1>>
1476    where
1477        I: IntoIterator<Item = Range<u32>>,
1478        F: FnMut(&[u8], &Range<u32>) -> bool,
1479    {
1480
1481        let Some(len) = checked_len(&dim) else { 
1482            return Err(bytes);
1483        };
1484
1485        let mut spans = spans.into_iter();
1486
1487        // With length zero we don't have to 
1488        if len == 0 {
1489            
1490            if spans.next().is_some() {
1491                return Err(bytes);
1492            }
1493
1494            // SAFETY: The storage holds no values, as many as the dimensions say.
1495            return Ok(unsafe { Self::from_raw(bytes.into_raw(), TableSpans::EMPTY, dim) });
1496
1497        }
1498
1499        // A single value takes no table, the buffer starting where it does, so nothing is
1500        // allocated, not even for an empty value within the empty storage.
1501        if len == 1 {
1502
1503            let Some(span) = spans.next().filter(|span| check(bytes.as_slice(), span)) else {
1504                return Err(bytes);
1505            };
1506
1507            if spans.next().is_some() {
1508                return Err(bytes);
1509            }
1510
1511            let mut raw = bytes.into_raw();
1512            raw.offset += span.start as usize;
1513            // SAFETY: The span was accepted, within the octets, which start further by its
1514            // start, and the dimensions say a single value.
1515            return Ok(unsafe { Self::from_raw(raw, TableSpans::single(span.len()), dim) });
1516            
1517        }
1518
1519        let Some(size) = len.checked_mul(mem::size_of::<Range<u32>>()) else { 
1520            return Err(bytes);
1521        };
1522
1523        let Ok(side) = DetachedSide::new(size) else { 
1524            return Err(bytes);
1525        };
1526
1527        let table = side.payload().cast::<Range<u32>>();
1528        for index in 0..len {
1529            let Some(span) = spans.next().filter(|span| check(bytes.as_slice(), span)) else { 
1530                return Err(bytes);
1531            };
1532            // SAFETY: The table holds that many spans, and is aligned for them.
1533            unsafe { table.add(index).write(span) };
1534        }
1535
1536        if spans.next().is_some() {
1537            return Err(bytes);
1538        }
1539
1540        let mut raw = bytes.into_raw();
1541        // Nothing is attached to the empty storage: empty values within it are given a
1542        // storage of their own, which they need no octets of.
1543        if raw.inner.is_immortal() {
1544            raw = HeapRef { inner: infallible(Heap::alloc(0)), offset: 0 };
1545        }
1546        raw.inner.push_side(side);
1547
1548        // SAFETY: The spans were all accepted, as many as the dimensions say.
1549        Ok(unsafe { Self::from_raw(raw, TableSpans(table), dim) })
1550        
1551    }
1552
1553}
1554
1555impl<const DIM: usize> Buf<str, DIM> {
1556
1557    /// The strings at these spans of these octets, relative to them, with those
1558    /// dimensions, sharing their storage. The octets are given back if the spans are not as
1559    /// many as the dimensions say, are out of the octets, or are not valid UTF-8.
1560    ///
1561    /// This is how a backend decodes strings out of the message it received, the spans
1562    /// being typically given as it reads them.
1563    pub fn from_spans<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Result<Self, Buf<u8, 1>>
1564    where
1565        I: IntoIterator<Item = Range<u32>>,
1566    {
1567        Self::with_spans(bytes, spans, dim, |bytes, span| {
1568            bytes.get(span.start as usize..span.end as usize).is_some_and(str::validate)
1569        })
1570    }
1571
1572    /// The unchecked form of [`Self::from_spans`], for a backend that already validated
1573    /// the strings: only their number is checked.
1574    ///
1575    /// # Safety
1576    ///
1577    /// The spans must be within the octets, and valid UTF-8 there.
1578    ///
1579    /// # Panics
1580    ///
1581    /// If the spans are not as many as the dimensions say, or if their table cannot be
1582    /// allocated.
1583    #[inline]
1584    #[track_caller]
1585    pub unsafe fn from_spans_unchecked<I>(bytes: Buf<u8, 1>, spans: I, dim: [usize; DIM]) -> Self
1586    where
1587        I: IntoIterator<Item = Range<u32>>,
1588    {
1589        Self::with_spans(bytes, spans, dim, |_, _| true)
1590            .unwrap_or_else(|_| panic!("no table of as many spans as the dimensions {dim:?} say"))
1591    }
1592
1593}
1594
1595impl Buf<str, 1> {
1596
1597    /// A buffer of copies of these strings, as many as there are. Absent if several of them
1598    /// do not fit spans of 32 bits.
1599    ///
1600    /// A single string is copied into a storage of its own, its span taking no table, so
1601    /// it allocates nothing more, and nothing at all when it is empty.
1602    pub fn from_strs<I>(values: I) -> Option<Self>
1603    where
1604        I: IntoIterator,
1605        I::Item: AsRef<str>,
1606    {
1607
1608        let mut values = values.into_iter();
1609
1610        let Some(first) = values.next() else {
1611            // SAFETY: The empty storage holds no values, as many as the dimensions say.
1612            return Some(unsafe { Self::from_raw(HeapRef::EMPTY, TableSpans::EMPTY, [0]) });
1613        };
1614
1615        let Some(second) = values.next() else {
1616            let value = first.as_ref();
1617            let raw = if value.is_empty() { HeapRef::EMPTY } else { infallible(HeapRef::copy(value.as_bytes(), 0)) };
1618            // SAFETY: The storage holds that single string where the buffer starts.
1619            return Some(unsafe { Self::from_raw(raw, TableSpans::single(value.len()), [1]) });
1620        };
1621
1622        let mut buf = BufMut::<u8, 1>::new();
1623        // The size hint only tells how many spans to make room for: the strings are copied
1624        // as they come, whatever it said.
1625        let mut spans = Vec::with_capacity(values.size_hint().0.saturating_add(2));
1626
1627        for value in [first, second].into_iter().chain(values) {
1628            let start = u32::try_from(buf.len()).ok()?;
1629            buf.extend_from_slice(value.as_ref().as_bytes());
1630            spans.push(start..u32::try_from(buf.len()).ok()?);
1631        }
1632
1633        let len = spans.len();
1634        // SAFETY: The spans are those of the strings just written, as many as the
1635        // dimensions say.
1636        Some(unsafe { Self::from_spans_unchecked(buf.freeze(), spans, [len]) })
1637
1638    }
1639
1640}
1641
1642impl From<&str> for Buf<str, 0> {
1643    /// A scalar of a copy of that string, which is its only allocation, none if it is
1644    /// empty.
1645    #[inline]
1646    fn from(value: &str) -> Self {
1647        Buf::<str, 1>::from_strs([value])
1648            .and_then(Buf::into_scalar)
1649            .expect("a single string always makes a scalar")
1650    }
1651}
1652
1653impl From<Cow<'_, str>> for Buf<str, 0> {
1654    /// A scalar of a copy of that string.
1655    #[inline]
1656    fn from(value: Cow<'_, str>) -> Self {
1657        Self::from(&*value)
1658    }
1659}
1660
1661impl From<String> for Buf<str, 0> {
1662    /// A scalar of a copy of that string.
1663    #[inline]
1664    fn from(value: String) -> Self {
1665        Self::from(value.as_str())
1666    }
1667}
1668
1669impl<S: AsRef<str>> From<&[S]> for Buf<str, 1> {
1670    #[inline]
1671    fn from(values: &[S]) -> Self {
1672        Self::from_strs(values).expect("strings of more than 4 GiB")
1673    }
1674}
1675
1676
1677// =========================== //
1678//       Writable buffers      //
1679// =========================== //
1680
1681/// A buffer of packed values that is statically the only reference to its storage, like a
1682/// `Vec`: it is written without ever checking whether its storage is shared, it grows
1683/// along one dimension, and it turns into a [`Buf`] to be shared, see [`Self::freeze`]. A [`Buf`] turns
1684/// into one with copy-on-write, see [`Buf::make_mut`] and [`Buf::into_mut`].
1685///
1686/// It cannot be sliced, which would share its storage, and cloning it copies its values
1687/// into a storage of their own, like a `Vec`. An empty one may have no storage of its own,
1688/// see [`Self::new`], until it first grows.
1689#[repr(transparent)]
1690pub struct BufMut<T: PackedElement, const DIM: usize>(Buf<T, DIM>);
1691
1692impl<T: PackedElement, const DIM: usize> BufMut<T, DIM> {
1693
1694    /// A buffer of zeroes with those dimensions, held in place for a scalar.
1695    ///
1696    /// # Panics
1697    ///
1698    /// If the dimensions are too large for a storage.
1699    pub fn zeroed(dim: [usize; DIM]) -> Self {
1700
1701        let size = checked_len(&dim)
1702            .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1703            .expect("capacity overflow");
1704
1705        if Buf::<T, DIM>::INLINE || size == 0 {
1706            // SAFETY: Zeroes are valid values of a packed type, as many as the dimensions say.
1707            return Self(unsafe { Buf::copy_from_bytes(&[0; mem::size_of::<Repr>()][..size], dim) });
1708        }
1709
1710        let raw = HeapRef { inner: infallible(Heap::alloc(size)), offset: 0 };
1711
1712        // SAFETY: A new storage is aligned for any packed type, and holds zeroes.
1713        Self(unsafe { Buf::from_raw(raw, PackedSpans::new(), dim) })
1714        
1715    }
1716
1717    /// A buffer of these values, see [`Buf::from_slice`].
1718    #[inline]
1719    pub fn from_slice(values: &[T], dim: [usize; DIM]) -> Option<Self> {
1720        Buf::from_slice(values, dim).map(Self)
1721    }
1722
1723    /// The dimensions of this buffer, see [`Buf::dim`].
1724    #[inline]
1725    pub fn dim(&self) -> [usize; DIM] {
1726        self.0.dim
1727    }
1728
1729    /// The number of values of this buffer, 1 for a scalar.
1730    #[inline]
1731    pub fn len(&self) -> usize {
1732        self.0.len()
1733    }
1734
1735    #[inline]
1736    pub fn is_empty(&self) -> bool {
1737        self.0.is_empty()
1738    }
1739
1740    /// Where the values of this buffer start.
1741    #[inline]
1742    pub fn as_ptr(&self) -> *const T {
1743        self.0.as_ptr()
1744    }
1745
1746    #[inline]
1747    pub fn as_slice(&self) -> &[T] {
1748        self.0.as_slice()
1749    }
1750
1751    #[inline]
1752    pub fn as_mut_slice(&mut self) -> &mut [T] {
1753        let len = self.len();
1754        // SAFETY: The buffer holds that many aligned values, in a storage it alone references.
1755        unsafe { slice::from_raw_parts_mut(self.0.base_mut().cast::<T>(), len) }
1756    }
1757
1758    #[inline]
1759    pub fn as_bytes(&self) -> &[u8] {
1760        self.0.as_bytes()
1761    }
1762
1763    /// Share this buffer, which cannot be written anymore unless it is the only reference
1764    /// to its storage again, see [`Buf::try_into_mut`].
1765    #[inline]
1766    pub fn freeze(self) -> Buf<T, DIM> {
1767        self.0
1768    }
1769
1770}
1771
1772impl<T: PackedElement> BufMut<T, 1> {
1773
1774    /// An empty buffer, which allocates nothing until it grows, see [`Buf::new`].
1775    #[inline]
1776    pub const fn new() -> Self {
1777        Self(Buf::new())
1778    }
1779
1780    /// An empty buffer that can grow to at least that many values without reallocating.
1781    #[inline]
1782    pub fn with_capacity(capacity: usize) -> Self {
1783        let mut buf = Self::new();
1784        buf.reserve(capacity);
1785        buf
1786    }
1787
1788    /// How many values this buffer can hold without reallocating.
1789    #[inline]
1790    pub fn capacity(&self) -> usize {
1791        let raw = self.0.raw();
1792        (raw.inner.capacity() - raw.offset) / mem::size_of::<T>()
1793    }
1794
1795    /// Where the value at that index is, which may be past the length but not past the
1796    /// capacity.
1797    #[inline]
1798    fn ptr_at(&self, index: usize) -> *mut T {
1799        debug_assert!(index <= self.capacity());
1800        // SAFETY: The index is within the capacity.
1801        unsafe { self.0.raw().ptr().cast::<T>().add(index) }
1802    }
1803
1804    /// Make room for at least that many more values, growing the storage if it lacks room.
1805    #[inline]
1806    pub fn reserve(&mut self, additional: usize) {
1807        infallible(self.alloc_reserve(additional))
1808    }
1809
1810    /// [`Self::reserve`], failing rather than aborting when the allocation does, which
1811    /// leaves the buffer as it was: for a length that comes off the wire.
1812    pub fn try_reserve(&mut self, additional: usize) -> Result<(), Error> {
1813        self.alloc_reserve(additional).map_err(|_| Error::new(ErrorKind::Internal)
1814            .with_description(format!("Failed to allocate room for {additional} more values behind {}", self.len())))
1815    }
1816
1817    fn alloc_reserve(&mut self, additional: usize) -> AllocResult<()> {
1818        let len = self.len();
1819        let raw = self.0.raw_mut();
1820        let end = len.checked_add(additional)
1821            .and_then(|len| len.checked_mul(mem::size_of::<T>()))
1822            .and_then(|size| raw.offset.checked_add(size))
1823            .ok_or(None)?;
1824        if end <= raw.inner.capacity() {
1825            return Ok(());
1826        }
1827        if raw.inner.is_immortal() {
1828            // The empty storage is never written, a buffer grows out of it into a storage
1829            // of its own, which it starts at, its offset in the empty storage being zero.
1830            raw.inner = Heap::alloc(end)?;
1831        } else {
1832            // SAFETY: The buffer is the only reference to its storage.
1833            unsafe { raw.inner.grow(end)? };
1834        }
1835        Ok(())
1836    }
1837
1838    /// Append that value.
1839    #[inline]
1840    pub fn push(&mut self, value: T) {
1841        self.reserve(1);
1842        // SAFETY: There is room for it, in a storage this buffer alone references.
1843        unsafe { self.ptr_at(self.len()).write(value) };
1844        self.0.dim[0] += 1;
1845    }
1846
1847    /// Append these values.
1848    pub fn extend_from_slice(&mut self, values: &[T]) {
1849        self.reserve(values.len());
1850        // SAFETY: There is room for them, in a storage this buffer alone references.
1851        unsafe { ptr::copy_nonoverlapping(values.as_ptr(), self.ptr_at(self.len()), values.len()) };
1852        self.0.dim[0] += values.len();
1853    }
1854
1855    /// Grow or shrink to that many values, the added ones being that value.
1856    ///
1857    /// Zeroes are only written up to the capacity this buffer had before growing: what a
1858    /// storage grows by is already zeroed.
1859    pub fn resize(&mut self, len: usize, value: T) {
1860        let old_len = self.len();
1861        if len > old_len {
1862            // SAFETY: A packed type has no padding, so its value is all initialized octets.
1863            let bytes = unsafe { slice::from_raw_parts(ptr::from_ref(&value).cast::<u8>(), mem::size_of::<T>()) };
1864            let end = if bytes.iter().all(|&octet| octet == 0) {
1865                // Values that are partly within the old capacity are written.
1866                let raw = self.0.raw();
1867                len.min((raw.inner.capacity() - raw.offset).div_ceil(mem::size_of::<T>()))
1868            } else {
1869                len
1870            };
1871            self.reserve(len - old_len);
1872            for index in old_len..end {
1873                // SAFETY: There is room for it, in a storage this buffer alone references.
1874                unsafe { self.ptr_at(index).write(value) };
1875            }
1876        }
1877        self.0.dim[0] = len;
1878    }
1879
1880    /// Keep only the first values, no more than that many.
1881    #[inline]
1882    pub fn truncate(&mut self, len: usize) {
1883        self.0.truncate(len);
1884    }
1885
1886    /// Empty this buffer, keeping its storage, and so its capacity, and freeing what the
1887    /// buffers cast from it had attached to it.
1888    pub fn clear(&mut self) {
1889        let raw = self.0.raw_mut();
1890        if !raw.inner.is_immortal() {
1891            // SAFETY: The buffer is the only reference to its storage.
1892            unsafe { raw.inner.free_sides() };
1893        }
1894        raw.offset = 0;
1895        self.0.dim[0] = 0;
1896    }
1897
1898}
1899
1900impl BufMut<u8, 1> {
1901
1902    /// Parse plain hexadecimal octets, in either case, which is what [`UpperHex`] and
1903    /// [`LowerHex`] give, absent if they are not.
1904    pub fn from_hex(s: &str) -> Option<Self> {
1905        if !s.len().is_multiple_of(2) {
1906            return None;
1907        }
1908        let mut buf = Self::with_capacity(s.len() / 2);
1909        for hex in s.as_bytes().as_chunks::<2>().0 {
1910            let hex = str::from_utf8(hex).ok()?;
1911            buf.push(u8::from_str_radix(hex, 16).ok()?);
1912        }
1913        Some(buf)
1914    }
1915
1916    /// Grow or shrink to that many octets, the added ones being left as they are, which
1917    /// saves zeroing octets that are about to be written: they are zeroes, unless this
1918    /// buffer held something there before it was shrunk or cleared.
1919    ///
1920    /// This is only for octets, every one of which is valid, unlike what was left there
1921    /// for other types.
1922    pub fn set_len(&mut self, len: usize) {
1923        self.reserve(len.saturating_sub(self.len()));
1924        self.0.dim[0] = len;
1925    }
1926
1927}
1928
1929// --- Standard traits impl --- //
1930
1931impl<T: PackedElement, const DIM: usize> Clone for BufMut<T, DIM> {
1932    /// A copy of the values of this buffer, in a storage of their own, the capacity past
1933    /// them not being kept.
1934    #[inline]
1935    fn clone(&self) -> Self {
1936        // SAFETY: The octets are those of the values of this buffer.
1937        Self(unsafe { Buf::copy_from_bytes(self.as_bytes(), self.dim()) })
1938    }
1939}
1940
1941impl<T: PackedElement> Default for BufMut<T, 1> {
1942    #[inline]
1943    fn default() -> Self {
1944        Self::new()
1945    }
1946}
1947
1948impl<T: PackedElement + PartialEq, const DIM: usize> PartialEq for BufMut<T, DIM> {
1949    #[inline]
1950    fn eq(&self, other: &Self) -> bool {
1951        self.dim() == other.dim() && self.as_slice() == other.as_slice()
1952    }
1953}
1954
1955impl<T: PackedElement + Eq, const DIM: usize> Eq for BufMut<T, DIM> {}
1956
1957impl<T: PackedElement> From<&[T]> for BufMut<T, 1> {
1958    #[inline]
1959    fn from(values: &[T]) -> Self {
1960        Self(Buf::from(values))
1961    }
1962}
1963
1964impl<T: PackedElement> From<Vec<T>> for BufMut<T, 1> {
1965    #[inline]
1966    fn from(values: Vec<T>) -> Self {
1967        Self::from(values.as_slice())
1968    }
1969}
1970
1971// --- Formatters --- //
1972
1973impl<T: PackedElement, const DIM: usize> Debug for BufMut<T, DIM> {
1974    /// Its dimensions and values, row by row, see [`Element::fmt_row`].
1975    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1976        fmt_buf::<T, _>(f, "BufMut", &self.0.dim, self.0.iter())
1977    }
1978}
1979
1980impl<T: PackedElement> UpperHex for BufMut<T, 1> {
1981    /// The octets of the values as hexadecimal, in the order they are stored, each value's
1982    /// grouped and separated by a space, octets being a single run that
1983    /// [`BufMut::from_hex`] parses back.
1984    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1985        fmt_hex::<T>(self.as_bytes(), f, true)
1986    }
1987}
1988
1989impl<T: PackedElement> LowerHex for BufMut<T, 1> {
1990    /// The octets of the values as hexadecimal, in the order they are stored, each value's
1991    /// grouped and separated by a space, octets being a single run that
1992    /// [`BufMut::from_hex`] parses back.
1993    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1994        fmt_hex::<T>(self.as_bytes(), f, false)
1995    }
1996}
1997
1998#[cfg(test)]
1999#[allow(clippy::single_range_in_vec_init)]
2000mod tests {
2001
2002    use super::*;
2003
2004    /// A scalar of a packed type is held in place: it has no storage to share, so it is
2005    /// always unique, and its only value is at the empty position.
2006    #[test]
2007    fn scalar() {
2008        let scalar = Buf::<f64, 0>::from(1.5);
2009        assert_eq!(scalar.value(), 1.5);
2010        assert_eq!(scalar.get([]), Some(1.5));
2011        assert_eq!(scalar.len(), 1);
2012        let clone = scalar.clone();
2013        assert!(scalar.is_unique() && clone.is_unique());
2014    }
2015
2016    #[test]
2017    fn one_dim() {
2018        let buf = Buf::<i32, 1>::from(vec![1, 2, 3]);
2019        assert_eq!(buf.dim(), [3]);
2020        assert_eq!(buf.get([1]), Some(2));
2021        assert_eq!(buf.get([3]), None);
2022        assert_eq!(buf.as_slice(), &[1, 2, 3]);
2023        assert_eq!(buf.iter().sum::<i32>(), 6);
2024    }
2025
2026    /// Two dimensions are in column-major order: `[x, y]`, with `x` varying the fastest, so
2027    /// a 3×2 buffer is its two rows one after the other.
2028    #[test]
2029    fn two_dim() {
2030        let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
2031        assert_eq!(buf.get([0, 1]), Some(4));
2032        assert_eq!(buf.get([2, 1]), Some(6));
2033        assert_eq!(buf.get([3, 0]), None);
2034        assert_eq!(buf.raw_index([1, 1]), Some(4));
2035        assert_eq!(buf.get_raw(4), Some(5));
2036        // The dimensions have to account for every value.
2037        assert!(Buf::<u8, 2>::from_slice(&[1, 2, 3], [2, 2]).is_none());
2038        // And can be changed afterwards, as long as they still do.
2039        let flat = buf.reshape([6]).unwrap();
2040        assert_eq!(flat.as_slice(), &[1, 2, 3, 4, 5, 6]);
2041    }
2042
2043    /// Empty buffers allocate nothing, all sharing the same static storage, which is never
2044    /// written: growing one first gives it a storage of its own.
2045    #[test]
2046    fn empty() {
2047        const EMPTY: Buf<u32, 2> = Buf::new();
2048        const EMPTY_MUT: BufMut<u8, 1> = BufMut::new();
2049        assert_eq!(EMPTY.dim(), [0, 0]);
2050        assert!(!EMPTY.is_unique());
2051        let mut values = Buf::<u32, 1>::from(vec![]);
2052        assert_eq!(values.as_ptr().cast::<u8>(), EMPTY_MUT.as_ptr());
2053        assert_eq!(values.make_mut().as_mut_slice(), &mut []);
2054        assert!(Buf::<str, 1>::from(&[] as &[&str]).iter().next().is_none());
2055        // Empty strings within an empty buffer have their spans attached elsewhere.
2056        let strings = Buf::<str, 1>::from_spans(values.into_bytes(), [0..0, 0..0], [2]).unwrap();
2057        assert_eq!(strings.iter().collect::<Vec<_>>(), ["", ""]);
2058        let mut buf = EMPTY_MUT;
2059        assert_eq!(buf.capacity(), 0);
2060        buf.clear();
2061        buf.extend_from_slice(&[]);
2062        assert_eq!(buf.as_ptr(), EMPTY_MUT.as_ptr());
2063        buf.extend_from_slice(&[1, 2]);
2064        assert_ne!(buf.as_ptr(), EMPTY_MUT.as_ptr());
2065        let mut shared = EMPTY.reshape::<1>([0]).unwrap();
2066        shared.get_mut().unwrap().resize(3, 7);
2067        assert_eq!(shared.as_slice(), [7; 3]);
2068    }
2069
2070    /// Cloning a writable buffer copies its values, both copies staying unique.
2071    #[test]
2072    fn writable_clone() {
2073        let mut buf = BufMut::from(&[1u16, 2][..]);
2074        let mut copy = buf.clone();
2075        assert_ne!(copy.as_ptr(), buf.as_ptr());
2076        copy.as_mut_slice()[0] = 0;
2077        buf.push(3);
2078        assert_eq!((buf.as_slice(), copy.as_slice()), (&[1, 2, 3][..], &[0, 2][..]));
2079        assert!(buf.freeze().is_unique() && copy.freeze().is_unique());
2080    }
2081
2082    /// Values taken out of a buffer turn back into the part of it they are, as long as they
2083    /// are a range of its last dimension.
2084    #[test]
2085    fn slicing_by_ref() {
2086        let values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2087        let part = values.slice_ref(&values.as_slice()[1..3]);
2088        assert_eq!(part.as_slice(), &[2, 3]);
2089        assert_eq!(part.as_ptr(), values.as_slice()[1..].as_ptr());
2090        let rows = values.reshape([2, 2]).unwrap();
2091        assert_eq!(rows.slice_ref(&rows.as_slice()[2..]).dim(), [2, 1]);
2092        let res = std::panic::catch_unwind(|| rows.slice_ref(&rows.as_slice()[1..3]));
2093        assert!(res.is_err());
2094        let other = [3, 4];
2095        let res = std::panic::catch_unwind(|| rows.slice_ref(&other));
2096        assert!(res.is_err());
2097    }
2098
2099    /// A decoder's slice of octets turns back into the part of the buffer it is.
2100    #[test]
2101    fn octets_by_ref() {
2102        let buf = Buf::from(&b"hello world"[..]);
2103        let part = buf.slice_ref(&buf.as_slice()[6..]);
2104        assert_eq!(part.as_slice(), b"world");
2105        assert!(buf.slice_ref(&buf.as_slice()[11..]).is_empty());
2106    }
2107
2108    /// Slicing cuts along the last dimension, values for one dimension or rows for two,
2109    /// and shares the storage rather than copying.
2110    #[test]
2111    fn slicing() {
2112        let buf = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2113        let rows = buf.slice(1..);
2114        assert_eq!(rows.dim(), [2, 2]);
2115        assert_eq!(rows.as_slice(), &[3, 4, 5, 6]);
2116        assert!(!buf.is_unique());
2117        assert_eq!(rows.slice(..1).as_slice(), &[3, 4]);
2118    }
2119
2120    /// A scalar is one value: it is reshaped to and from anything of one value, a packed one
2121    /// moving in and out of place.
2122    #[test]
2123    fn scalar_shapes() {
2124        let scalar = Buf::<u16, 0>::from(7);
2125        let square = scalar.clone().reshape([1, 1]).unwrap();
2126        assert_eq!(square.as_slice(), &[7]);
2127        assert!(scalar.clone().reshape([2]).is_none());
2128        assert_eq!(square.into_scalar().unwrap(), scalar);
2129        assert_eq!(scalar.clone().into_scalar().unwrap(), scalar);
2130        let string = Buf::<str, 0>::from("ab");
2131        let strings = string.clone().reshape([1]).unwrap();
2132        assert!(!string.is_unique());
2133        assert_eq!(strings.into_scalar().unwrap().value(), "ab");
2134    }
2135
2136    /// Splitting shares the storage, each side keeping its part.
2137    #[test]
2138    fn splitting() {
2139        let mut buf = Buf::from(&b"headtail"[..]);
2140        let head = buf.split_to(4);
2141        assert_eq!((head.as_slice(), buf.as_slice()), (&b"head"[..], &b"tail"[..]));
2142        let tail = buf.split_off(2);
2143        assert_eq!((buf.as_slice(), tail.as_slice()), (&b"ta"[..], &b"il"[..]));
2144        assert!(!head.is_unique());
2145        let mut rows = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2146        assert_eq!(rows.split_to(1).as_slice(), &[1, 2]);
2147        assert_eq!(rows.dim(), [2, 2]);
2148    }
2149
2150    #[test]
2151    #[should_panic(expected = "out of range")]
2152    fn slice_out_of_range() {
2153        Buf::<u8, 1>::from(vec![1, 2]).slice(1..3);
2154    }
2155
2156    /// A scalar held in place is written in place.
2157    #[test]
2158    fn scalar_mutation() {
2159        let mut scalar = Buf::<i32, 0>::from(1);
2160        scalar.make_mut().as_mut_slice()[0] = 2;
2161        assert_eq!(scalar.value(), 2);
2162        assert_eq!(BufMut::<i32, 0>::zeroed([]).freeze().value(), 0);
2163    }
2164
2165    /// A single value is taken out as a scalar: in place for a packed one, sharing the
2166    /// storage for a string.
2167    #[test]
2168    fn scalar_extraction() {
2169        let values = Buf::<f64, 1>::from(vec![1.5, 2.5]);
2170        assert_eq!(values.slice(1..).into_scalar().unwrap().value(), 2.5);
2171        assert!(values.is_unique());
2172        assert!(values.clone().into_scalar().is_none());
2173        let strings = Buf::<str, 1>::from(&["ab", "cd"][..]);
2174        let scalar = strings.slice(1..).into_scalar().unwrap();
2175        assert_eq!(scalar.value(), "cd");
2176        assert!(!strings.is_unique());
2177        assert_eq!(strings.get_scalar([0]).unwrap().value(), "ab");
2178        assert!(strings.get_scalar([2]).is_none());
2179        let image = Buf::<u8, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [2, 3]).unwrap();
2180        assert_eq!(image.get_scalar([1, 2]).unwrap().value(), 6);
2181        assert_eq!(Buf::<u16, 0>::from(7).get_scalar([]).unwrap().value(), 7);
2182    }
2183
2184    /// Writing to a shared buffer first copies it, only its own values and not the whole
2185    /// storage, so that what shares the storage is never affected.
2186    #[test]
2187    fn copy_on_write() {
2188        let mut values = Buf::<u16, 1>::from(vec![1, 2, 3, 4]);
2189        let part = values.slice(1..3);
2190        values.make_mut().as_mut_slice()[1] = 9;
2191        assert_eq!(values.as_slice(), &[1, 9, 3, 4]);
2192        assert_eq!(part.as_slice(), &[2, 3]);
2193        assert!(values.is_unique());
2194        // A unique buffer is written in place.
2195        let ptr = values.as_ptr();
2196        values.make_mut().as_mut_slice()[0] = 0;
2197        assert_eq!(values.as_ptr(), ptr);
2198        // And a shared one turned into a writable one only takes its own values.
2199        let rest = Buf::from(vec![0u16; 64]).slice(1..);
2200        let part = rest.slice(..2).into_mut();
2201        assert_ne!(part.as_ptr(), rest.as_ptr());
2202        assert!(part.capacity() < rest.len());
2203    }
2204
2205    /// A shared buffer grows through copy-on-write, what was sharing its storage keeping
2206    /// the octets it had.
2207    #[test]
2208    fn copy_on_write_growth() {
2209        let mut buf = Buf::from(&b"head"[..]);
2210        let head = buf.clone();
2211        buf.make_mut().extend_from_slice(b" tail");
2212        assert_eq!((buf.as_slice(), head.as_slice()), (&b"head tail"[..], &b"head"[..]));
2213    }
2214
2215    /// A buffer of one dimension grows like a `Vec`, whatever its type.
2216    #[test]
2217    fn growth() {
2218        let mut buf = BufMut::<u32, 1>::with_capacity(4);
2219        buf.extend_from_slice(&[1, 2]);
2220        buf.resize(5, 0);
2221        buf.extend_from_slice(&[7; 100]);
2222        buf.push(8);
2223        assert_eq!(buf.len(), 106);
2224        assert_eq!(buf.as_slice()[..6], [1, 2, 0, 0, 0, 7]);
2225        assert_eq!(buf.as_slice()[105], 8);
2226        buf.truncate(2);
2227        assert_eq!(buf.as_slice(), &[1, 2]);
2228    }
2229
2230    /// Setting the length of octets grows without zeroing: what the buffer held there
2231    /// before it shrank is still there, and octets it never held are zeroes.
2232    #[test]
2233    fn length() {
2234        let mut buf = BufMut::from(&[0xAA; 8][..]);
2235        buf.truncate(4);
2236        buf.set_len(12);
2237        assert_eq!(buf.as_slice(), [&[0xAA; 8][..], &[0; 4]].concat());
2238        buf.truncate(4);
2239        buf.resize(8, 0);
2240        assert_eq!(buf.as_slice(), [0xAA, 0xAA, 0xAA, 0xAA, 0, 0, 0, 0]);
2241    }
2242
2243    /// Resizing with zeroes zeroes what the buffer held within its capacity, and relies on
2244    /// what it grows by being zeroed already.
2245    #[test]
2246    fn zero_resize() {
2247        let mut buf = BufMut::from(&[0xAAAAu16; 4][..]);
2248        buf.clear();
2249        buf.resize(100, 0);
2250        assert_eq!(buf.as_slice(), [0; 100]);
2251        buf.clear();
2252        buf.resize(2, 0xBBBB);
2253        buf.resize(3, 0);
2254        assert_eq!(buf.as_slice(), [0xBBBB, 0xBBBB, 0]);
2255    }
2256
2257    /// A reservation that cannot be allocated fails and leaves the buffer as it was.
2258    #[test]
2259    fn reservation() {
2260        let mut buf = BufMut::from(&[1u16, 2][..]);
2261        assert!(buf.try_reserve(usize::MAX).is_err());
2262        assert!(buf.try_reserve(isize::MAX as usize).is_err());
2263        assert_eq!(buf.as_slice(), [1, 2]);
2264        buf.reserve(64);
2265        assert!(buf.capacity() >= 66);
2266    }
2267
2268    /// Clearing a buffer keeps its storage for the next message, and so does freezing it
2269    /// once what was shared out of it is gone.
2270    #[test]
2271    fn recycling() {
2272        let mut buf = BufMut::from(&b"first"[..]);
2273        let ptr = buf.as_ptr();
2274        buf.clear();
2275        buf.extend_from_slice(b"second");
2276        assert_eq!(buf.as_ptr(), ptr);
2277
2278        let buf = buf.freeze();
2279        let first = Buf::<str, 0>::from_spans(buf.slice(..3), [0..3], []).unwrap();
2280        let buf = buf.try_into_mut().unwrap_err();
2281        drop(first);
2282        let mut buf = buf.try_into_mut().unwrap();
2283        buf.clear();
2284        assert_eq!(buf.as_ptr(), ptr);
2285    }
2286
2287    /// A shared buffer only turns back into a writable one, without copying, once nothing
2288    /// else references its storage.
2289    #[test]
2290    fn unique_buffer() {
2291        let buf = Buf::from(&[1u8, 2, 3][..]);
2292        let ptr = buf.as_ptr();
2293        let part = buf.slice(1..);
2294        let mut buf = buf.try_into_mut().unwrap_err();
2295        assert!(buf.get_mut().is_none());
2296        drop(part);
2297        buf.get_mut().unwrap().truncate(1);
2298        let buf = buf.try_into_mut().unwrap();
2299        assert_eq!(buf.as_ptr(), ptr);
2300        assert_eq!(buf.as_slice(), [1]);
2301    }
2302
2303    /// Casting octets to packed values shares the storage when they are aligned for the
2304    /// type, and copies them otherwise, which is always correct and only slower.
2305    #[test]
2306    fn packed_cast() {
2307        let buf = Buf::<u32, 1>::from(vec![1, 2, 3, 4]).into_bytes();
2308        let aligned = buf.slice(8..).cast::<u32, 1>([2]).unwrap();
2309        assert_eq!(aligned.as_slice(), &[3, 4]);
2310        assert!(!aligned.is_unique());
2311        let unaligned = buf.slice(1..9).cast::<u32, 1>([2]).unwrap();
2312        assert!(unaligned.is_unique());
2313        // The octets must be exactly those of the dimensions, the buffer being given back
2314        // if they are not.
2315        let buf = buf.cast::<u32, 1>([3]).unwrap_err();
2316        // A scalar is always copied in place.
2317        assert!(buf.slice(..2).cast::<u16, 0>([]).unwrap().is_unique());
2318        // And any packed type casts to any other.
2319        let halves = aligned.cast::<u16, 2>([2, 2]).unwrap();
2320        assert_eq!(halves.cast::<u64, 0>([]).unwrap().value(), 3 | 4 << 32);
2321    }
2322
2323    /// A buffer starting where its storage starts is currently aligned for every packed
2324    /// type, which is not part of the API.
2325    #[test]
2326    fn storage_alignment() {
2327        let buf = Buf::from(&[0u8; 16][..]);
2328        assert_eq!(buf.as_ptr().addr() % ALIGN, 0);
2329        assert!(!buf.clone().cast::<f64, 1>([2]).unwrap().is_unique());
2330    }
2331
2332    /// Not every octet pattern is a value: a boolean is only 0 or 1.
2333    #[test]
2334    fn invalid_values() {
2335        let buf = Buf::from(&[0u8, 1, 2][..]);
2336        assert!(buf.slice(..2).cast::<bool, 1>([2]).is_ok());
2337        assert!(buf.cast::<bool, 1>([3]).is_err());
2338    }
2339
2340    /// A buffer gives its octets back, which is what it is encoded from.
2341    #[test]
2342    fn octets_round_trip() {
2343        let values = Buf::<u16, 1>::from(vec![1, 2]);
2344        assert_eq!(values.as_bytes(), [1u16.to_ne_bytes(), 2u16.to_ne_bytes()].concat());
2345        let buf = values.into_bytes();
2346        assert_eq!(buf.cast::<u16, 1>([2]).unwrap().as_slice(), &[1, 2]);
2347    }
2348
2349    #[test]
2350    fn strings() {
2351        let strings = Buf::<str, 1>::from(&["ab", "", "cde"][..]);
2352        assert_eq!(strings.get([2]), Some("cde"));
2353        assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2354        assert_eq!(strings.slice(1..).get([1]), Some("cde"));
2355        assert_eq!(Buf::<str, 0>::from("scalar").value(), "scalar");
2356    }
2357
2358    /// Strings copied out of an iterator, as many as it gives whatever its size hint says,
2359    /// empty ones and no string at all included.
2360    #[test]
2361    fn strings_from_iter() {
2362        let strings = Buf::<str, 1>::from_strs(["ab", "", "cde"].into_iter().filter(|_| true)).unwrap();
2363        assert_eq!(strings.dim(), [3]);
2364        assert_eq!(strings.iter().collect::<Vec<_>>(), ["ab", "", "cde"]);
2365        let empty = Buf::<str, 1>::from_strs(std::iter::empty::<&str>()).unwrap();
2366        assert!(empty.is_empty());
2367    }
2368
2369    /// Strings decoded from octets are found at the spans the decoder gives, relative to
2370    /// the octets, and share their storage: they outlive the buffer of octets.
2371    #[test]
2372    fn string_spans() {
2373        let msg = Buf::from(&b"..hello world"[..]);
2374        let strings = Buf::<str, 1>::from_spans(msg.slice(2..), [0..5, 6..11], [2]).unwrap();
2375        drop(msg);
2376        assert_eq!(strings.iter().collect::<Vec<_>>(), ["hello", "world"]);
2377        // Every span is checked: within the octets, not inverted, and valid UTF-8.
2378        let buf = Buf::from(&[b'a', 0xff][..]);
2379        let buf = Buf::<str, 1>::from_spans(buf, [0..3], [1]).unwrap_err();
2380        let buf = Buf::<str, 1>::from_spans(buf, [1..2], [1]).unwrap_err();
2381        #[allow(clippy::reversed_empty_ranges)]
2382        let buf = Buf::<str, 1>::from_spans(buf, [1..0], [1]).unwrap_err();
2383        assert!(Buf::<str, 0>::from_spans(buf, [0..1], []).is_ok());
2384    }
2385
2386    /// A single string takes no table of spans: it shares the storage of its octets, and
2387    /// an empty one built out of nothing allocates nothing at all.
2388    #[test]
2389    fn single_string() {
2390        let msg = Buf::from(&b"..hello world"[..]);
2391        let hello = Buf::<str, 0>::from_spans(msg.slice(2..), [0..5], []).unwrap();
2392        let world = Buf::<str, 1>::from_spans(msg.slice(2..), [6..11], [1]).unwrap();
2393        drop(msg);
2394        assert_eq!(hello.value(), "hello");
2395        assert_eq!(world.iter().collect::<Vec<_>>(), ["world"]);
2396        assert_eq!(world.get_scalar([0]).unwrap().value(), "world");
2397        assert!(world.slice(1..).is_empty());
2398        assert_eq!(world.slice(..1).reshape([1, 1]).unwrap().get([0, 0]), Some("world"));
2399        assert_eq!(world.into_scalar().unwrap().value(), "world");
2400        let buf = Buf::from(&b"ab"[..]);
2401        let buf = Buf::<str, 0>::from_spans(buf, [0..1, 1..2], []).unwrap_err();
2402        assert!(Buf::<str, 0>::from_spans(buf, [], []).is_err());
2403        let empty = Buf::<str, 0>::from("");
2404        assert_eq!(empty.value(), "");
2405        assert!(!empty.is_unique());
2406    }
2407
2408    /// Spans are given as the decoder reads them, and must be exactly as many as the
2409    /// dimensions say, which nothing is attached to the storage for when they are not.
2410    #[test]
2411    fn span_iterator() {
2412        let msg = Buf::from(&b"a,bc,def"[..]);
2413        let spans = msg.as_slice().split(|&b| b == b',').scan(0, |start, part| {
2414            let span = *start..*start + part.len() as u32;
2415            *start = span.end + 1;
2416            Some(span)
2417        }).collect::<Vec<_>>();
2418        let strings = Buf::<str, 1>::from_spans(msg.clone(), spans.clone(), [3]).unwrap();
2419        assert_eq!(strings.iter().collect::<Vec<_>>(), ["a", "bc", "def"]);
2420        let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [2]).unwrap_err();
2421        let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [4]).unwrap_err();
2422        let msg = Buf::<str, 1>::from_spans(msg, spans.clone(), [usize::MAX]).unwrap_err();
2423        assert!(Buf::<str, 1>::from_spans(msg, [], [0]).is_ok());
2424    }
2425
2426    #[test]
2427    fn thread_sharing() {
2428        let values = Buf::<f64, 1>::from(vec![1.0, 2.0]);
2429        let sum = std::thread::spawn({
2430            let values = values.clone();
2431            move || values.iter().sum::<f64>()
2432        });
2433        assert_eq!(sum.join().unwrap(), 3.0);
2434    }
2435
2436    /// A state is packed like a number, only its known values being valid ones.
2437    #[test]
2438    fn states() {
2439        let buf = Buf::from(&[DevState::Moving as u8, 200][..]);
2440        let buf = buf.cast::<DevState, 1>([2]).unwrap_err();
2441        assert_eq!(buf.slice(..1).cast::<DevState, 0>([]).unwrap().value(), DevState::Moving);
2442    }
2443
2444    /// Buffers are equal when their dimensions and values are, wherever they are stored.
2445    #[test]
2446    fn equality() {
2447        let values = Buf::<i32, 1>::from([1, 2, 3, 4]);
2448        assert_eq!(values.slice(2..), Buf::from([3, 4]));
2449        assert_ne!(values.clone().reshape([2, 2]).unwrap(), Buf::from_slice(&[1, 2, 3, 4], [4, 1]).unwrap());
2450    }
2451
2452    /// Only the first values of a buffer are shown.
2453    #[test]
2454    fn debug() {
2455        assert_eq!(format!("{:?}", Buf::<u16, 1>::from([7; 3])), "Buf<3>[7, 7, 7]");
2456        assert_eq!(format!("{:?}", Buf::<u16, 0>::from(7)), "Buf(7)");
2457        let rows = Buf::<i32, 2>::from_slice(&[1, 2, 3, 4, 5, 6], [3, 2]).unwrap();
2458        assert_eq!(format!("{rows:?}"), "Buf<3, 2>[[1, 2, 3], [4, 5, 6]]");
2459        assert_eq!(format!("{rows:#?}"), "Buf<3, 2>[\n    [1, 2, 3],\n    [4, 5, 6],\n]");
2460        assert_eq!(format!("{:?}", BufMut::<u8, 2>::zeroed([2, 0])), "BufMut<2, 0>[]");
2461        assert_eq!(format!("{:?}", Buf::<u8, 2>::new().reshape([0, 2]).unwrap()), "Buf<0, 2>[[], []]");
2462        assert_eq!(format!("{:?}", Buf::<str, 1>::from(&["a", "b"][..])), r#"Buf<2>["a", "b"]"#);
2463    }
2464
2465    /// Octets are shown in hexadecimal, all of them, with runs of readable ASCII quoted.
2466    #[test]
2467    fn octets_debug() {
2468        assert_eq!(format!("{:?}", Buf::from(&b"\x01\x02GIOP\x00"[..])), "Buf<7>[01 02 'GIOP' 00]");
2469        assert_eq!(format!("{:?}", BufMut::<u8, 1>::from(vec![0xAB; 20])), format!("BufMut<20>[{}AB]", "AB ".repeat(19)));
2470        let rows = Buf::<u8, 2>::from_slice(b"ab\x01\x02", [2, 2]).unwrap();
2471        assert_eq!(format!("{rows:?}"), "Buf<2, 2>[['ab'], [01 02]]");
2472    }
2473
2474    /// Octets are formatted as plain hexadecimal, which is parsed back, and other packed
2475    /// values as the groups of their octets.
2476    #[test]
2477    fn hex() {
2478        let buf = Buf::from(&[0x01, 0xAB, 0x00][..]);
2479        assert_eq!(format!("{buf:X}"), "01AB00");
2480        assert_eq!(format!("{buf:x}"), "01ab00");
2481        assert_eq!(format!("{:X}", buf.clone().into_mut()), "01AB00");
2482        assert_eq!(BufMut::from_hex("01AB00").unwrap().freeze(), buf);
2483        assert_eq!(BufMut::from_hex("01ab00").unwrap().freeze(), buf);
2484        assert!(BufMut::from_hex("01A").is_none());
2485        assert!(BufMut::from_hex("0G").is_none());
2486        // Larger values are grouped, in the order their octets are stored.
2487        let words = Buf::<u16, 1>::from([0x0102, 0xABCD]);
2488        let expected = if cfg!(target_endian = "little") { "0201 cdab" } else { "0102 abcd" };
2489        assert_eq!(format!("{words:x}"), expected);
2490        assert_eq!(format!("{:X}", Buf::<u32, 1>::new()), "");
2491    }
2492
2493    /// A buffer is a reference to a storage and its dimensions, nothing more: the spans of
2494    /// a packed type take no room, and a table is one pointer.
2495    #[test]
2496    fn sizes() {
2497        assert_eq!(mem::size_of::<Buf<f64, 0>>(), 16);
2498        assert_eq!(mem::size_of::<Buf<u8, 1>>(), 24);
2499        assert_eq!(mem::size_of::<Buf<f64, 2>>(), 32);
2500        assert_eq!(mem::size_of::<Buf<str, 1>>(), 32);
2501        assert_eq!(mem::size_of::<BufMut<u8, 1>>(), 24);
2502    }
2503
2504}