o3/buffer/storage/inline/
mod.rs1use std::{hash, mem};
2
3pub use append::Append;
4
5use crate::{
6 buffer,
7 buffer::{bytes, storage::inline, write, write::consume::Error},
8};
9
10pub const CAPACITY: usize = 24;
11
12mod append;
13
14pub struct Fill<'a, const LEFT: usize, L = u16> {
16 output: &'a mut [u8; LEFT],
17 len: &'a mut L,
18}
19
20impl<'a, const LEFT: usize, L: crate::buffer::raw::Length> Fill<'a, LEFT, L> {
21 pub fn new(target: &'a mut inline::Bytes<LEFT, L>) -> Self {
22 target.len = L::ZERO;
23 Self {
24 output: &mut target.bytes,
25 len: &mut target.len,
26 }
27 }
28
29 pub fn write<const MAX: usize, const NEXT: usize>(
30 self,
31 source: bytes::Prefix<'_, MAX>,
32 ) -> (Fill<'a, NEXT, L>, &'a mut [u8]) {
33 const { assert!(MAX <= LEFT && NEXT == LEFT - MAX) }
34 let source = source.as_slice();
35 let (copied, output) = unsafe { self.output.split_at_mut_unchecked(source.len()) };
38 inline::Append::new(copied, self.len).write(|output| output.copy_from_slice(source));
39 (
40 Fill {
41 output: unsafe { &mut *output.as_mut_ptr().cast::<[u8; NEXT]>() },
43 len: self.len,
44 },
45 copied,
46 )
47 }
48
49 pub fn finish(self, source: bytes::Prefix<'_, LEFT>) {
51 let _ = self.write::<LEFT, 0>(source);
52 }
53}
54
55const _: () = assert!(mem::size_of::<Fill<'_, 284>>() == 2 * mem::size_of::<usize>());
56
57#[repr(C)]
59#[derive(Clone, Copy, Debug)]
60pub struct Bytes<const CAP: usize = { CAPACITY }, L = u8> {
61 pub(in crate::buffer::storage::inline) bytes: [u8; CAP],
62 pub(in crate::buffer::storage::inline) len: L,
63}
64
65impl<const CAP: usize, L: crate::buffer::raw::Length> Bytes<CAP, L> {
66 const VALID: () = assert!(CAP <= L::MAX, "inline byte capacity exceeds length field");
67
68 #[must_use]
69 pub const fn new() -> Self {
70 let () = Self::VALID;
71 Self {
72 bytes: [0; CAP],
73 len: L::ZERO,
74 }
75 }
76
77 pub fn from_slice(bytes: &[u8]) -> Result<Self, Error> {
78 let mut inline = Self::new();
79 write::Sink::write_slice(&mut inline, bytes)?;
80 Ok(inline)
81 }
82
83 pub fn try_reserve(&mut self, amount: usize) -> Result<inline::Append<'_, L>, Error> {
85 Error::check(amount, self.available())?;
86 Ok(self.fit(amount))
87 }
88
89 pub fn fit(&mut self, amount: usize) -> inline::Append<'_, L> {
91 let start = self.len();
92 let end = start + amount.min(CAP - start);
93 let output = unsafe { self.bytes.get_unchecked_mut(start..end) };
95 inline::Append::new(output, &mut self.len)
96 }
97
98 pub fn try_replace<const N: usize>(
102 &mut self,
103 start: usize,
104 limit: usize,
105 slices: [&[u8]; N],
106 ) -> Result<(), Error> {
107 let start = start.min(self.len());
108 let end = Error::checked_end(start, limit.min(CAP), &slices)?;
109 unsafe {
112 buffer::raw::SliceExt::copy_to(&slices, self.bytes.as_mut_ptr().add(start));
113 }
114 self.len = L::from_usize(end);
115 Ok(())
116 }
117
118 pub fn truncate(&mut self, len: usize) {
119 if len < self.len() {
120 self.len = L::from_usize(len);
121 }
122 }
123
124 pub fn clear(&mut self) {
125 self.len = L::ZERO;
126 }
127
128 pub fn len(&self) -> usize {
129 self.len.into_usize()
130 }
131
132 pub fn is_empty(&self) -> bool {
133 self.len() == 0
134 }
135
136 pub fn available(&self) -> usize {
137 CAP - self.len()
138 }
139
140 pub fn backing_mut(&mut self) -> &mut [u8; CAP] {
142 &mut self.bytes
143 }
144}
145
146impl<const CAP: usize, L: crate::buffer::raw::Length> Default for Bytes<CAP, L> {
147 fn default() -> Self {
148 Self::new()
149 }
150}
151
152impl<const CAP: usize, L: crate::buffer::raw::Length, const N: usize> From<[u8; N]>
153 for Bytes<CAP, L>
154{
155 fn from(bytes: [u8; N]) -> Self {
156 const { assert!(N <= CAP, "inline array must fit its backing capacity") };
157 Self::from(bytes::Prefix::<CAP>::new(&bytes))
158 }
159}
160
161impl<const CAP: usize, L: crate::buffer::raw::Length> From<bytes::Prefix<'_, CAP>>
162 for Bytes<CAP, L>
163{
164 fn from(source: bytes::Prefix<'_, CAP>) -> Self {
165 let mut prefix = Self::new();
166 let source = source.as_slice();
167 unsafe { buffer::raw::SliceExt::copy_to(source, prefix.bytes.as_mut_ptr()) };
169 prefix.len = L::from_usize(source.len());
170 prefix
171 }
172}
173
174impl<const CAP: usize, L: crate::buffer::raw::Length> PartialEq for Bytes<CAP, L> {
175 fn eq(&self, other: &Self) -> bool {
176 self.as_ref() == other.as_ref()
177 }
178}
179
180impl<const CAP: usize, L: crate::buffer::raw::Length> Eq for Bytes<CAP, L> {}
181
182impl<const CAP: usize, L: crate::buffer::raw::Length> hash::Hash for Bytes<CAP, L> {
183 fn hash<H: hash::Hasher>(&self, state: &mut H) {
184 self.as_ref().hash(state);
185 }
186}
187
188impl<const CAP: usize, L: crate::buffer::raw::Length> AsRef<[u8]> for Bytes<CAP, L> {
189 fn as_ref(&self) -> &[u8] {
190 unsafe { self.bytes.get_unchecked(..self.len()) }
192 }
193}
194
195impl<const CAP: usize, L: crate::buffer::raw::Length> AsMut<[u8]> for Bytes<CAP, L> {
196 fn as_mut(&mut self) -> &mut [u8] {
197 let len = self.len();
198 unsafe { self.bytes.get_unchecked_mut(..len) }
200 }
201}
202
203impl<const CAP: usize, L: crate::buffer::raw::Length> write::Sink for Bytes<CAP, L> {
204 type Error = Error;
205
206 fn write_slice(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
207 self.try_reserve(bytes.len())?
208 .write(|output| output.copy_from_slice(bytes));
209 Ok(())
210 }
211
212 fn write_slices<const N: usize>(&mut self, slices: [&[u8]; N]) -> Result<(), Self::Error> {
213 self.try_replace(self.len(), CAP, slices)
214 }
215}
216
217unsafe impl<const CAP: usize, L> buffer::raw::Source for Bytes<CAP, L> where
219 Bytes<CAP, L>: AsRef<[u8]>
220{
221}