Skip to main content

httpbis/bytes_ext/
bytes_deque.rs

1use crate::bytes_ext::buf_eq::buf_eq;
2use crate::bytes_ext::bytes_vec_deque::BytesVecDeque;
3use crate::bytes_ext::iter_buf::IterBuf;
4use crate::BufGetBytes;
5use bytes::Buf;
6use bytes::Bytes;
7use std::collections::vec_deque;
8use std::io::IoSlice;
9use std::mem;
10
11#[derive(Debug)]
12enum Inner {
13    One(Bytes),
14    Deque(BytesVecDeque),
15}
16
17impl Default for Inner {
18    fn default() -> Self {
19        Inner::One(Bytes::new())
20    }
21}
22
23/// `VecDeque<Bytes>` but slightly more efficient.
24#[derive(Debug, Default)]
25pub struct BytesDeque(Inner);
26
27impl BytesDeque {
28    /// Empty deque.
29    pub fn new() -> BytesDeque {
30        Default::default()
31    }
32
33    /// Create a deque by copying from bytes slice.
34    pub fn copy_from_slice(bytes: &[u8]) -> BytesDeque {
35        BytesDeque::from(Bytes::copy_from_slice(bytes))
36    }
37
38    /// Length in bytes.
39    pub fn len(&self) -> usize {
40        match &self.0 {
41            Inner::One(b) => b.len(),
42            Inner::Deque(d) => d.len(),
43        }
44    }
45
46    /// Append [`Bytes`] to this deque.
47    pub fn extend(&mut self, bytes: Bytes) {
48        if bytes.is_empty() {
49            return;
50        }
51
52        match &mut self.0 {
53            Inner::One(one) if one.is_empty() => {
54                self.0 = Inner::One(bytes);
55            }
56            Inner::One(one) => {
57                self.0 = Inner::Deque(BytesVecDeque::from(vec![mem::take(one), bytes]));
58            }
59            Inner::Deque(deque) if deque.len() == 0 => {
60                self.0 = Inner::One(bytes);
61            }
62            Inner::Deque(deque) => {
63                deque.extend(bytes);
64            }
65        }
66    }
67
68    /// Get deque contents as [`Bytes`] object.
69    ///
70    /// This operation is cheap if this deque contains only single [`Bytes`] object,
71    /// otherwise it allocates memory and copies data.
72    pub fn get_bytes(&self) -> Bytes {
73        match &self.0 {
74            Inner::One(b) => b.clone(),
75            Inner::Deque(d) => d.get_bytes(),
76        }
77    }
78
79    /// Convert contents into [`Bytes`] object.
80    ///
81    /// This function tries to avoid memory allocation when possible.
82    pub fn into_bytes(self) -> Bytes {
83        match self.0 {
84            Inner::One(b) => b,
85            Inner::Deque(d) => d.into_bytes(),
86        }
87    }
88
89    fn iter_buf<'a>(&'a self) -> IterBuf<Bytes, impl Iterator<Item = Bytes> + 'a> {
90        IterBuf::new(self.into_iter().cloned(), self.remaining())
91    }
92}
93
94impl PartialEq<BytesDeque> for BytesDeque {
95    fn eq(&self, other: &BytesDeque) -> bool {
96        buf_eq(self.iter_buf(), other.iter_buf())
97    }
98}
99
100impl PartialEq<[u8]> for BytesDeque {
101    fn eq(&self, other: &[u8]) -> bool {
102        buf_eq(self.iter_buf(), other)
103    }
104}
105
106impl From<Bytes> for BytesDeque {
107    fn from(b: Bytes) -> Self {
108        BytesDeque(Inner::One(b))
109    }
110}
111
112impl From<Vec<u8>> for BytesDeque {
113    fn from(v: Vec<u8>) -> Self {
114        BytesDeque::from(Bytes::from(v))
115    }
116}
117
118impl<'a> From<&'a str> for BytesDeque {
119    fn from(s: &'a str) -> Self {
120        BytesDeque::from(Bytes::copy_from_slice(s.as_bytes()))
121    }
122}
123
124impl Into<Bytes> for BytesDeque {
125    fn into(self) -> Bytes {
126        self.into_bytes()
127    }
128}
129
130impl Into<Vec<u8>> for BytesDeque {
131    fn into(self) -> Vec<u8> {
132        match self.0 {
133            Inner::One(b) => Vec::from(b.as_ref()),
134            Inner::Deque(d) => d.into(),
135        }
136    }
137}
138
139impl Buf for BytesDeque {
140    fn remaining(&self) -> usize {
141        match &self.0 {
142            Inner::One(b) => b.remaining(),
143            Inner::Deque(d) => d.remaining(),
144        }
145    }
146
147    fn bytes(&self) -> &[u8] {
148        match &self.0 {
149            Inner::One(b) => b.bytes(),
150            Inner::Deque(d) => d.bytes(),
151        }
152    }
153
154    fn bytes_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize {
155        match &self.0 {
156            Inner::One(b) => b.bytes_vectored(dst),
157            Inner::Deque(d) => d.bytes_vectored(dst),
158        }
159    }
160
161    fn advance(&mut self, cnt: usize) {
162        match &mut self.0 {
163            Inner::One(b) => b.advance(cnt),
164            Inner::Deque(d) => d.advance(cnt),
165        }
166    }
167}
168
169impl BufGetBytes for BytesDeque {
170    fn get_bytes(&mut self, cnt: usize) -> Bytes {
171        match &mut self.0 {
172            Inner::One(b) => b.get_bytes(cnt),
173            Inner::Deque(d) => d.get_bytes(cnt),
174        }
175    }
176}
177
178pub enum Iter<'a> {
179    One(Option<&'a Bytes>),
180    Deque(vec_deque::Iter<'a, Bytes>),
181}
182
183impl<'a> Iterator for Iter<'a> {
184    type Item = &'a Bytes;
185
186    fn next(&mut self) -> Option<Self::Item> {
187        match self {
188            Iter::One(b) => b.take(),
189            Iter::Deque(d) => d.next(),
190        }
191    }
192}
193
194impl<'a> IntoIterator for &'a BytesDeque {
195    type Item = &'a Bytes;
196    type IntoIter = Iter<'a>;
197
198    fn into_iter(self) -> Self::IntoIter {
199        match &self.0 {
200            Inner::One(b) => Iter::One(Some(b)),
201            Inner::Deque(d) => Iter::Deque((&d).into_iter()),
202        }
203    }
204}
205
206#[cfg(test)]
207mod test {
208    use super::*;
209    use rand::thread_rng;
210    use rand::Rng;
211
212    fn extend_iter() {
213        let mut d = BytesDeque::new();
214        let mut reference = Vec::new();
215
216        for _ in 0..10 {
217            let bytes = if thread_rng().gen_range(0, 3) == 0 {
218                Bytes::new()
219            } else {
220                let len = thread_rng().gen_range(0, 10);
221                let mut v = Vec::new();
222                for _ in 0..len {
223                    v.push(thread_rng().gen());
224                }
225                Bytes::from(v)
226            };
227
228            reference.extend_from_slice(&bytes);
229            d.extend(bytes);
230        }
231
232        assert_eq!(reference, Into::<Vec<u8>>::into(d));
233    }
234
235    #[test]
236    fn extend() {
237        for _ in 0..10000 {
238            extend_iter();
239        }
240    }
241}