1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use core::slice::SliceIndex;

use crate::traits::{UnsizedZeroCopy, ZeroCopy};
use crate::{Buf, ByteOrder, Error, Ref, Size};

mod sealed {
    #[cfg(feature = "alloc")]
    use crate::buf::OwnedBuf;
    use crate::buf::SliceMut;
    use crate::{ByteOrder, Size};

    pub trait Sealed {}

    impl<'a, E: ByteOrder, O: Size> Sealed for SliceMut<'a, E, O> {}

    #[cfg(feature = "alloc")]
    impl<E: ByteOrder, O: Size> Sealed for OwnedBuf<E, O> {}
}

/// A buffer that we can store things into.
#[allow(clippy::len_without_is_empty)]
pub trait StoreBuf: self::sealed::Sealed {
    /// The sticky endianness associated with the buffer.
    type ByteOrder: ByteOrder;

    /// The sticky size associated with the buffer.
    type Size: Size;

    /// The current initialized length of the buffer.
    #[doc(hidden)]
    fn len(&self) -> usize;

    /// Truncate the buffer to the given length.
    #[doc(hidden)]
    fn truncate(&mut self, len: usize);

    /// Store an unsigned value.
    #[doc(hidden)]
    fn store_unsized<T: ?Sized>(&mut self, value: &T) -> Ref<T, Self::ByteOrder, Self::Size>
    where
        T: UnsizedZeroCopy;

    /// Store a [`ZeroCopy`] value.
    #[doc(hidden)]
    fn store<T>(&mut self, value: &T) -> Ref<T, Self::ByteOrder, Self::Size>
    where
        T: ZeroCopy;

    /// Swap the location of two references.
    #[doc(hidden)]
    fn swap<T>(
        &mut self,
        a: Ref<T, Self::ByteOrder, Self::Size>,
        b: Ref<T, Self::ByteOrder, Self::Size>,
    ) -> Result<(), Error>
    where
        T: ZeroCopy;

    /// Ensure that the store buffer is aligned.
    ///
    /// For buffers which cannot be re-aligned, this will simply panic.
    #[doc(hidden)]
    fn align_in_place(&mut self);

    /// Construct an offset aligned for `T` into the current buffer which points
    /// to the next location that will be written.
    #[doc(hidden)]
    fn next_offset<T>(&mut self) -> usize;

    /// Align by `align` and `reserve` additional space in the buffer or panic.
    #[doc(hidden)]
    fn next_offset_with_and_reserve(&mut self, align: usize, reserve: usize);

    /// Fill the buffer with `len` repetitions of `byte`.
    #[doc(hidden)]
    fn fill(&mut self, byte: u8, len: usize);

    /// Get an immutable slice.
    #[doc(hidden)]
    fn get<I>(&self, index: I) -> Option<&I::Output>
    where
        I: SliceIndex<[u8]>;

    /// Get a mutable slice.
    #[doc(hidden)]
    fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
    where
        I: SliceIndex<[u8]>;

    /// Get the underlying buffer.
    #[doc(hidden)]
    fn as_buf(&self) -> &Buf;

    /// Get the underlying buffer mutably.
    #[doc(hidden)]
    fn as_mut_buf(&mut self) -> &mut Buf;
}