1use core::fmt;
24use core::convert::Infallible;
25#[cfg(feature = "bytes")] use bytes::{Bytes, BytesMut};
26#[cfg(feature = "std")] use std::borrow::Cow;
27#[cfg(feature = "std")] use std::vec::Vec;
28
29
30pub trait OctetsBuilder {
42 type AppendError: Into<ShortBuf>;
54
55 fn append_slice(
60 &mut self, slice: &[u8]
61 ) -> Result<(), Self::AppendError>;
62}
63
64impl<'a, T: OctetsBuilder> OctetsBuilder for &'a mut T {
65 type AppendError = T::AppendError;
66
67 fn append_slice(
68 &mut self, slice: &[u8]
69 ) -> Result<(), Self::AppendError> {
70 (*self).append_slice(slice)
71 }
72}
73
74#[cfg(feature = "std")]
75impl OctetsBuilder for Vec<u8> {
76 type AppendError = Infallible;
77
78 fn append_slice(
79 &mut self, slice: &[u8]
80 ) -> Result<(), Self::AppendError> {
81 self.extend_from_slice(slice);
82 Ok(())
83 }
84}
85
86#[cfg(feature = "std")]
87impl<'a> OctetsBuilder for Cow<'a, [u8]> {
88 type AppendError = Infallible;
89
90 fn append_slice(
91 &mut self, slice: &[u8]
92 ) -> Result<(), Self::AppendError> {
93 if let Cow::Owned(ref mut vec) = *self {
94 vec.extend_from_slice(slice);
95 } else {
96 let mut vec = std::mem::replace(
97 self, Cow::Borrowed(b"")
98 ).into_owned();
99 vec.extend_from_slice(slice);
100 *self = Cow::Owned(vec);
101 }
102 Ok(())
103 }
104}
105
106#[cfg(feature = "bytes")]
107impl OctetsBuilder for BytesMut {
108 type AppendError = Infallible;
109
110 fn append_slice(
111 &mut self, slice: &[u8]
112 ) -> Result<(), Self::AppendError> {
113 self.extend_from_slice(slice);
114 Ok(())
115 }
116}
117
118#[cfg(feature = "smallvec")]
119impl<A: smallvec::Array<Item = u8>> OctetsBuilder for smallvec::SmallVec<A> {
120 type AppendError = Infallible;
121
122 fn append_slice(
123 &mut self, slice: &[u8]
124 ) -> Result<(), Self::AppendError> {
125 self.extend_from_slice(slice);
126 Ok(())
127 }
128}
129
130#[cfg(feature = "heapless")]
131impl<const N: usize> OctetsBuilder for heapless::Vec<u8, N> {
132 type AppendError = ShortBuf;
133
134 fn append_slice(
135 &mut self, slice: &[u8]
136 ) -> Result<(), Self::AppendError> {
137 self.extend_from_slice(slice).map_err(|_| ShortBuf)
138 }
139}
140
141
142pub trait Truncate {
146 fn truncate(&mut self, len: usize);
150}
151
152impl<'a, T: Truncate> Truncate for &'a mut T {
153 fn truncate(&mut self, len: usize) {
154 (*self).truncate(len)
155 }
156}
157
158impl<'a> Truncate for &'a [u8] {
159 fn truncate(&mut self, len: usize) {
160 if len < self.len() {
161 *self = &self[..len]
162 }
163 }
164}
165
166#[cfg(feature = "std")]
167impl<'a> Truncate for Cow<'a, [u8]> {
168 fn truncate(&mut self, len: usize) {
169 match *self {
170 Cow::Borrowed(ref mut slice) => *slice = &slice[..len],
171 Cow::Owned(ref mut vec) => vec.truncate(len),
172 }
173 }
174}
175
176#[cfg(feature = "std")]
177impl Truncate for Vec<u8> {
178 fn truncate(&mut self, len: usize) {
179 self.truncate(len)
180 }
181}
182
183#[cfg(feature = "bytes")]
184impl Truncate for Bytes {
185 fn truncate(&mut self, len: usize) {
186 self.truncate(len)
187 }
188}
189
190#[cfg(feature = "bytes")]
191impl Truncate for BytesMut {
192 fn truncate(&mut self, len: usize) {
193 self.truncate(len)
194 }
195}
196
197#[cfg(feature = "smallvec")]
198impl<A: smallvec::Array<Item = u8>> Truncate for smallvec::SmallVec<A> {
199 fn truncate(&mut self, len: usize) {
200 self.truncate(len)
201 }
202}
203
204#[cfg(feature = "heapless")]
205impl<const N: usize> Truncate for heapless::Vec<u8, N> {
206 fn truncate(&mut self, len: usize) {
207 self.truncate(len)
208 }
209}
210
211
212pub trait EmptyBuilder {
216 fn empty() -> Self;
218
219 fn with_capacity(capacity: usize) -> Self;
227}
228
229#[cfg(feature = "std")]
230impl EmptyBuilder for Vec<u8> {
231 fn empty() -> Self {
232 Vec::new()
233 }
234
235 fn with_capacity(capacity: usize) -> Self {
236 Vec::with_capacity(capacity)
237 }
238}
239
240#[cfg(feature = "bytes")]
241impl EmptyBuilder for BytesMut {
242 fn empty() -> Self {
243 BytesMut::new()
244 }
245
246 fn with_capacity(capacity: usize) -> Self {
247 BytesMut::with_capacity(capacity)
248 }
249}
250
251#[cfg(feature = "smallvec")]
252impl<A: smallvec::Array<Item = u8>> EmptyBuilder for smallvec::SmallVec<A> {
253 fn empty() -> Self {
254 smallvec::SmallVec::new()
255 }
256
257 fn with_capacity(capacity: usize) -> Self {
258 smallvec::SmallVec::with_capacity(capacity)
259 }
260}
261
262#[cfg(feature = "heapless")]
263impl<const N: usize> EmptyBuilder for heapless::Vec<u8, N> {
264 fn empty() -> Self {
265 Self::new()
266 }
267
268 fn with_capacity(capacity: usize) -> Self {
269 debug_assert!(capacity <= N);
270 heapless::Vec::new()
272 }
273}
274
275
276pub trait FreezeBuilder {
280 type Octets;
282
283 fn freeze(self) -> Self::Octets;
285}
286
287#[cfg(feature = "std")]
288impl FreezeBuilder for Vec<u8> {
289 type Octets = Self;
290
291 fn freeze(self) -> Self::Octets {
292 self
293 }
294}
295
296#[cfg(feature = "std")]
297impl<'a> FreezeBuilder for Cow<'a, [u8]> {
298 type Octets = Self;
299
300 fn freeze(self) -> Self::Octets {
301 self
302 }
303}
304
305#[cfg(feature = "bytes")]
306impl FreezeBuilder for BytesMut {
307 type Octets = Bytes;
308
309 fn freeze(self) -> Self::Octets {
310 BytesMut::freeze(self)
311 }
312}
313
314#[cfg(feature = "smallvec")]
315impl<A: smallvec::Array<Item = u8>> FreezeBuilder for smallvec::SmallVec<A> {
316 type Octets = Self;
317
318 fn freeze(self) -> Self::Octets {
319 self
320 }
321}
322
323#[cfg(feature = "heapless")]
324impl<const N: usize> FreezeBuilder for heapless::Vec<u8, N> {
325 type Octets = Self;
326
327 fn freeze(self) -> Self::Octets {
328 self
329 }
330}
331
332
333pub trait IntoBuilder {
337 type Builder: OctetsBuilder;
339
340 fn into_builder(self) -> Self::Builder;
342}
343
344#[cfg(feature = "std")]
345impl IntoBuilder for Vec<u8> {
346 type Builder = Self;
347
348 fn into_builder(self) -> Self::Builder {
349 self
350 }
351}
352
353#[cfg(feature = "std")]
354impl<'a> IntoBuilder for &'a [u8] {
355 type Builder = Vec<u8>;
356
357 fn into_builder(self) -> Self::Builder {
358 self.into()
359 }
360}
361
362#[cfg(feature = "std")]
363impl<'a> IntoBuilder for Cow<'a, [u8]> {
364 type Builder = Self;
365
366 fn into_builder(self) -> Self::Builder {
367 self
368 }
369}
370
371#[cfg(feature = "bytes")]
372impl IntoBuilder for Bytes {
373 type Builder = BytesMut;
374
375 fn into_builder(self) -> Self::Builder {
376 BytesMut::from(self.as_ref())
380 }
381}
382
383#[cfg(feature = "smallvec")]
384impl<A: smallvec::Array<Item = u8>> IntoBuilder for smallvec::SmallVec<A> {
385 type Builder = Self;
386
387 fn into_builder(self) -> Self::Builder {
388 self
389 }
390}
391
392#[cfg(feature = "heapless")]
393impl<const N: usize> IntoBuilder for heapless::Vec<u8, N> {
394 type Builder = Self;
395
396 fn into_builder(self) -> Self::Builder {
397 self
398 }
399}
400
401
402pub trait FromBuilder: AsRef<[u8]> + Sized {
406 type Builder: OctetsBuilder + FreezeBuilder<Octets = Self>;
408
409 fn from_builder(builder: Self::Builder) -> Self;
411}
412
413#[cfg(feature = "std")]
414impl FromBuilder for Vec<u8> {
415 type Builder = Self;
416
417 fn from_builder(builder: Self::Builder) -> Self {
418 builder
419 }
420}
421
422#[cfg(feature = "std")]
423impl<'a> FromBuilder for Cow<'a, [u8]> {
424 type Builder = Self;
425
426 fn from_builder(builder: Self::Builder) -> Self {
427 builder
428 }
429}
430
431#[cfg(feature = "bytes")]
432impl FromBuilder for Bytes {
433 type Builder = BytesMut;
434
435 fn from_builder(builder: Self::Builder) -> Self {
436 builder.freeze()
437 }
438}
439
440#[cfg(feature = "smallvec")]
441impl<A: smallvec::Array<Item = u8>> FromBuilder for smallvec::SmallVec<A> {
442 type Builder = Self;
443
444 fn from_builder(builder: Self::Builder) -> Self {
445 builder
446 }
447}
448
449#[cfg(feature = "heapless")]
450impl<const N: usize> FromBuilder for heapless::Vec<u8, N> {
451 type Builder = Self;
452
453 fn from_builder(builder: Self::Builder) -> Self {
454 builder
455 }
456}
457
458
459pub type BuilderAppendError<Octets>
466 = <<Octets as FromBuilder>::Builder as OctetsBuilder>::AppendError;
467
468
469#[derive(Clone, Debug, Eq, PartialEq)]
481pub struct ShortBuf;
482
483
484impl From<Infallible> for ShortBuf {
487 fn from(_: Infallible) -> ShortBuf {
488 unreachable!()
489 }
490}
491
492
493impl fmt::Display for ShortBuf {
496 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
497 f.write_str("buffer size exceeded")
498 }
499}
500
501#[cfg(feature = "std")]
502impl std::error::Error for ShortBuf {}
503
504
505pub fn infallible<T, E: Into<Infallible>>(src: Result<T, E>) -> T {
515 match src {
516 Ok(ok) => ok,
517 Err(_) => unreachable!(),
518 }
519}
520
521pub fn with_infallible<F, T, E>(op: F) -> T
528where
529 F: FnOnce() -> Result<T, E>,
530 E: Into<Infallible>,
531{
532 infallible(op())
533}
534