Coverage Report

Created: 2024-12-17 06:15

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