mqi/mq/
buffer.rs

1use std::{
2    borrow::{self, Cow},
3    cmp,
4};
5
6pub enum InqBuffer<'a, T> {
7    Slice(&'a mut [T]),
8    Owned(Vec<T>),
9}
10
11impl<'a, T> InqBuffer<'a, T> {
12    #[must_use]
13    pub fn truncate(self, len: usize) -> Self {
14        match self {
15            Self::Slice(s) => {
16                let buf_len = s.len();
17                Self::Slice(&mut s[..cmp::min(len, buf_len)])
18            }
19            Self::Owned(mut v) => {
20                v.truncate(len);
21                Self::Owned(v)
22            }
23        }
24    }
25}
26
27impl<'a, T> AsRef<[T]> for InqBuffer<'a, T> {
28    fn as_ref(&self) -> &[T] {
29        match self {
30            InqBuffer::Slice(s) => s,
31            InqBuffer::Owned(o) => o,
32        }
33    }
34}
35
36impl<'a, T> AsMut<[T]> for InqBuffer<'a, T> {
37    fn as_mut(&mut self) -> &mut [T] {
38        match self {
39            InqBuffer::Slice(s) => s,
40            InqBuffer::Owned(o) => o,
41        }
42    }
43}
44
45impl<'a, T: Clone> From<InqBuffer<'a, T>> for borrow::Cow<'a, [T]>
46where
47    [T]: ToOwned,
48{
49    fn from(value: InqBuffer<'a, T>) -> Self {
50        match value {
51            InqBuffer::Slice(s) => borrow::Cow::from(&*s),
52            InqBuffer::Owned(o) => o.into(),
53        }
54    }
55}
56
57pub trait Buffer<'a>: Sized + AsMut<[u8]> + AsRef<[u8]> {
58    #[must_use]
59    fn truncate(self, size: usize) -> Self;
60    fn split_at(self, at: usize) -> (Self, Self);
61    fn into_cow(self) -> Cow<'a, [u8]>;
62    fn len(&self) -> usize;
63
64    fn is_empty(&self) -> bool {
65        self.len() == 0
66    }
67}
68
69impl<'a> Buffer<'a> for &'a mut [u8] {
70    fn truncate(self, size: usize) -> Self {
71        let len = self.len();
72        &mut self[..cmp::min(size, len)]
73    }
74
75    fn into_cow(self) -> Cow<'a, [u8]> {
76        Cow::from(&*self)
77    }
78
79    fn len(&self) -> usize {
80        (**self).len()
81    }
82
83    fn split_at(self, at: usize) -> (Self, Self) {
84        self.split_at_mut(at)
85    }
86}
87
88impl<'a> Buffer<'a> for Vec<u8> {
89    fn truncate(self, size: usize) -> Self {
90        let mut vec = self;
91        Self::truncate(&mut vec, size);
92        vec.shrink_to_fit();
93        vec
94    }
95
96    fn into_cow(self) -> Cow<'a, [u8]> {
97        self.into()
98    }
99
100    fn len(&self) -> usize {
101        self.len()
102    }
103
104    fn split_at(self, at: usize) -> (Self, Self) {
105        if at == 0 {
106            (Self::new(), self) // No allocation when position is 0
107        } else {
108            let mut self_mut = self;
109            let tail = self_mut.split_off(at);
110            (self_mut, tail)
111        }
112    }
113}
114
115impl<'a> Buffer<'a> for InqBuffer<'a, u8> {
116    fn truncate(self, size: usize) -> Self {
117        Self::truncate(self, size)
118    }
119
120    fn into_cow(self) -> Cow<'a, [u8]> {
121        self.into()
122    }
123
124    fn len(&self) -> usize {
125        self.as_ref().len()
126    }
127
128    fn split_at(self, at: usize) -> (Self, Self) {
129        match self {
130            Self::Slice(s) => {
131                let (head, tail) = s.split_at(at);
132                (Self::Slice(head), Self::Slice(tail))
133            }
134            Self::Owned(v) => {
135                let (head, tail) = v.split_at(at);
136                (Self::Owned(head), Self::Owned(tail))
137            }
138        }
139    }
140}