1use core::fmt;
5
6pub trait BvllSink {
17 fn remaining_capacity(&self) -> Option<usize>;
19
20 fn write(&mut self, bytes: &[u8]) -> Result<(), SinkFull>;
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct SinkFull {
29 pub needed: usize,
31 pub available: usize,
33}
34
35impl fmt::Display for SinkFull {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(
38 f,
39 "sink full: need {}, have {}",
40 self.needed, self.available
41 )
42 }
43}
44
45impl core::error::Error for SinkFull {}
46
47impl BvllSink for &mut [u8] {
50 fn remaining_capacity(&self) -> Option<usize> {
51 Some(self.len())
52 }
53
54 fn write(&mut self, bytes: &[u8]) -> Result<(), SinkFull> {
55 if self.len() < bytes.len() {
56 return Err(SinkFull {
57 needed: bytes.len(),
58 available: self.len(),
59 });
60 }
61 let (head, tail) = core::mem::take(self).split_at_mut(bytes.len());
62 head.copy_from_slice(bytes);
63 *self = tail;
64 Ok(())
65 }
66}
67
68#[cfg(feature = "heapless")]
69impl<const N: usize> BvllSink for heapless::Vec<u8, N> {
70 fn remaining_capacity(&self) -> Option<usize> {
71 Some(N - self.len())
72 }
73
74 fn write(&mut self, bytes: &[u8]) -> Result<(), SinkFull> {
75 let available = N - self.len();
76 self.extend_from_slice(bytes).map_err(|_| SinkFull {
77 needed: bytes.len(),
78 available,
79 })
80 }
81}
82
83#[cfg(feature = "alloc")]
84impl BvllSink for alloc::vec::Vec<u8> {
85 fn remaining_capacity(&self) -> Option<usize> {
86 None
87 }
88
89 fn write(&mut self, bytes: &[u8]) -> Result<(), SinkFull> {
90 self.extend_from_slice(bytes);
91 Ok(())
92 }
93}
94
95#[cfg(feature = "bytes")]
96impl BvllSink for bytes::BytesMut {
97 fn remaining_capacity(&self) -> Option<usize> {
98 None
99 }
100
101 fn write(&mut self, bytes: &[u8]) -> Result<(), SinkFull> {
102 self.extend_from_slice(bytes);
103 Ok(())
104 }
105}