embedrs_bytes/buf/
chain.rs

1use {Buf, BufMut};
2#[cfg(feature = "std")]
3use iovec::IoVec;
4
5/// A `Chain` sequences two buffers.
6///
7/// `Chain` is an adapter that links two underlying buffers and provides a
8/// continous view across both buffers. It is able to sequence either immutable
9/// buffers ([`Buf`] values) or mutable buffers ([`BufMut`] values).
10///
11/// This struct is generally created by calling [`Buf::chain`]. Please see that
12/// function's documentation for more detail.
13///
14/// # Examples
15///
16/// ```
17/// use embedrs_bytes::{Bytes, Buf, IntoBuf};
18/// use embedrs_bytes::buf::Chain;
19///
20/// let buf = Bytes::from(&b"hello "[..]).into_buf()
21///             .chain(Bytes::from(&b"world"[..]));
22///
23/// let full: Bytes = buf.collect();
24/// assert_eq!(full[..], b"hello world"[..]);
25/// ```
26///
27/// [`Buf::chain`]: trait.Buf.html#method.chain
28/// [`Buf`]: trait.Buf.html
29/// [`BufMut`]: trait.BufMut.html
30#[derive(Debug)]
31pub struct Chain<T, U> {
32    a: T,
33    b: U,
34}
35
36impl<T, U> Chain<T, U> {
37    /// Creates a new `Chain` sequencing the provided values.
38    ///
39    /// # Examples
40    ///
41    /// ```
42    /// use embedrs_bytes::BytesMut;
43    /// use embedrs_bytes::buf::Chain;
44    ///
45    /// let buf = Chain::new(
46    ///     BytesMut::with_capacity(1024),
47    ///     BytesMut::with_capacity(1024));
48    ///
49    /// // Use the chained buffer
50    /// ```
51    pub fn new(a: T, b: U) -> Chain<T, U> {
52        Chain {
53            a: a,
54            b: b,
55        }
56    }
57
58    /// Gets a reference to the first underlying `Buf`.
59    ///
60    /// # Examples
61    ///
62    /// ```
63    /// use embedrs_bytes::{Bytes, Buf, IntoBuf};
64    ///
65    /// let buf = Bytes::from(&b"hello"[..]).into_buf()
66    ///             .chain(Bytes::from(&b"world"[..]));
67    ///
68    /// assert_eq!(buf.first_ref().get_ref()[..], b"hello"[..]);
69    /// ```
70    pub fn first_ref(&self) -> &T {
71        &self.a
72    }
73
74    /// Gets a mutable reference to the first underlying `Buf`.
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// use embedrs_bytes::{Bytes, Buf, IntoBuf};
80    ///
81    /// let mut buf = Bytes::from(&b"hello "[..]).into_buf()
82    ///                 .chain(Bytes::from(&b"world"[..]));
83    ///
84    /// buf.first_mut().set_position(1);
85    ///
86    /// let full: Bytes = buf.collect();
87    /// assert_eq!(full[..], b"ello world"[..]);
88    /// ```
89    pub fn first_mut(&mut self) -> &mut T {
90        &mut self.a
91    }
92
93    /// Gets a reference to the last underlying `Buf`.
94    ///
95    /// # Examples
96    ///
97    /// ```
98    /// use embedrs_bytes::{Bytes, Buf, IntoBuf};
99    ///
100    /// let buf = Bytes::from(&b"hello"[..]).into_buf()
101    ///             .chain(Bytes::from(&b"world"[..]));
102    ///
103    /// assert_eq!(buf.last_ref().get_ref()[..], b"world"[..]);
104    /// ```
105    pub fn last_ref(&self) -> &U {
106        &self.b
107    }
108
109    /// Gets a mutable reference to the last underlying `Buf`.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use embedrs_bytes::{Bytes, Buf, IntoBuf};
115    ///
116    /// let mut buf = Bytes::from(&b"hello "[..]).into_buf()
117    ///                 .chain(Bytes::from(&b"world"[..]));
118    ///
119    /// buf.last_mut().set_position(1);
120    ///
121    /// let full: Bytes = buf.collect();
122    /// assert_eq!(full[..], b"hello orld"[..]);
123    /// ```
124    pub fn last_mut(&mut self) -> &mut U {
125        &mut self.b
126    }
127
128    /// Consumes this `Chain`, returning the underlying values.
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use embedrs_bytes::{Bytes, Buf, IntoBuf};
134    ///
135    /// let buf = Bytes::from(&b"hello"[..]).into_buf()
136    ///             .chain(Bytes::from(&b"world"[..]));
137    ///
138    /// let (first, last) = buf.into_inner();
139    /// assert_eq!(first.get_ref()[..], b"hello"[..]);
140    /// assert_eq!(last.get_ref()[..], b"world"[..]);
141    /// ```
142    pub fn into_inner(self) -> (T, U) {
143        (self.a, self.b)
144    }
145}
146
147impl<T, U> Buf for Chain<T, U>
148    where T: Buf,
149          U: Buf,
150{
151    fn remaining(&self) -> usize {
152        self.a.remaining() + self.b.remaining()
153    }
154
155    fn bytes(&self) -> &[u8] {
156        if self.a.has_remaining() {
157            self.a.bytes()
158        } else {
159            self.b.bytes()
160        }
161    }
162
163    fn advance(&mut self, mut cnt: usize) {
164        let a_rem = self.a.remaining();
165
166        if a_rem != 0 {
167            if a_rem >= cnt {
168                self.a.advance(cnt);
169                return;
170            }
171
172            // Consume what is left of a
173            self.a.advance(a_rem);
174
175            cnt -= a_rem;
176        }
177
178        self.b.advance(cnt);
179    }
180
181    #[cfg(feature = "std")]
182    fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
183        let mut n = self.a.bytes_vec(dst);
184        n += self.b.bytes_vec(&mut dst[n..]);
185        n
186    }
187}
188
189impl<T, U> BufMut for Chain<T, U>
190    where T: BufMut,
191          U: BufMut,
192{
193    fn remaining_mut(&self) -> usize {
194        self.a.remaining_mut() + self.b.remaining_mut()
195    }
196
197    unsafe fn bytes_mut(&mut self) -> &mut [u8] {
198        if self.a.has_remaining_mut() {
199            self.a.bytes_mut()
200        } else {
201            self.b.bytes_mut()
202        }
203    }
204
205    unsafe fn advance_mut(&mut self, mut cnt: usize) {
206        let a_rem = self.a.remaining_mut();
207
208        if a_rem != 0 {
209            if a_rem >= cnt {
210                self.a.advance_mut(cnt);
211                return;
212            }
213
214            // Consume what is left of a
215            self.a.advance_mut(a_rem);
216
217            cnt -= a_rem;
218        }
219
220        self.b.advance_mut(cnt);
221    }
222
223    #[cfg(feature = "std")]
224    unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
225        let mut n = self.a.bytes_vec_mut(dst);
226        n += self.b.bytes_vec_mut(&mut dst[n..]);
227        n
228    }
229}