Coverage Report

Created: 2025-07-12 06:15

/rust/registry/src/index.crates.io-6f17d22bba15001f/bytes-1.10.1/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
2
#![doc(test(
3
    no_crate_inject,
4
    attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
5
))]
6
#![no_std]
7
#![cfg_attr(docsrs, feature(doc_cfg))]
8
9
//! Provides abstractions for working with bytes.
10
//!
11
//! The `bytes` crate provides an efficient byte buffer structure
12
//! ([`Bytes`]) and traits for working with buffer
13
//! implementations ([`Buf`], [`BufMut`]).
14
//!
15
//! # `Bytes`
16
//!
17
//! `Bytes` is an efficient container for storing and operating on contiguous
18
//! slices of memory. It is intended for use primarily in networking code, but
19
//! could have applications elsewhere as well.
20
//!
21
//! `Bytes` values facilitate zero-copy network programming by allowing multiple
22
//! `Bytes` objects to point to the same underlying memory. This is managed by
23
//! using a reference count to track when the memory is no longer needed and can
24
//! be freed.
25
//!
26
//! A `Bytes` handle can be created directly from an existing byte store (such as `&[u8]`
27
//! or `Vec<u8>`), but usually a `BytesMut` is used first and written to. For
28
//! example:
29
//!
30
//! ```rust
31
//! use bytes::{BytesMut, BufMut};
32
//!
33
//! let mut buf = BytesMut::with_capacity(1024);
34
//! buf.put(&b"hello world"[..]);
35
//! buf.put_u16(1234);
36
//!
37
//! let a = buf.split();
38
//! assert_eq!(a, b"hello world\x04\xD2"[..]);
39
//!
40
//! buf.put(&b"goodbye world"[..]);
41
//!
42
//! let b = buf.split();
43
//! assert_eq!(b, b"goodbye world"[..]);
44
//!
45
//! assert_eq!(buf.capacity(), 998);
46
//! ```
47
//!
48
//! In the above example, only a single buffer of 1024 is allocated. The handles
49
//! `a` and `b` will share the underlying buffer and maintain indices tracking
50
//! the view into the buffer represented by the handle.
51
//!
52
//! See the [struct docs](`Bytes`) for more details.
53
//!
54
//! # `Buf`, `BufMut`
55
//!
56
//! These two traits provide read and write access to buffers. The underlying
57
//! storage may or may not be in contiguous memory. For example, `Bytes` is a
58
//! buffer that guarantees contiguous memory, but a [rope] stores the bytes in
59
//! disjoint chunks. `Buf` and `BufMut` maintain cursors tracking the current
60
//! position in the underlying byte storage. When bytes are read or written, the
61
//! cursor is advanced.
62
//!
63
//! [rope]: https://en.wikipedia.org/wiki/Rope_(data_structure)
64
//!
65
//! ## Relation with `Read` and `Write`
66
//!
67
//! At first glance, it may seem that `Buf` and `BufMut` overlap in
68
//! functionality with [`std::io::Read`] and [`std::io::Write`]. However, they
69
//! serve different purposes. A buffer is the value that is provided as an
70
//! argument to `Read::read` and `Write::write`. `Read` and `Write` may then
71
//! perform a syscall, which has the potential of failing. Operations on `Buf`
72
//! and `BufMut` are infallible.
73
74
extern crate alloc;
75
76
#[cfg(feature = "std")]
77
extern crate std;
78
79
pub mod buf;
80
pub use crate::buf::{Buf, BufMut};
81
82
mod bytes;
83
mod bytes_mut;
84
mod fmt;
85
mod loom;
86
pub use crate::bytes::Bytes;
87
pub use crate::bytes_mut::BytesMut;
88
89
// Optional Serde support
90
#[cfg(feature = "serde")]
91
mod serde;
92
93
#[inline(never)]
94
#[cold]
95
0
fn abort() -> ! {
96
0
    #[cfg(feature = "std")]
97
0
    {
98
0
        std::process::abort();
99
    }
100
101
    #[cfg(not(feature = "std"))]
102
    {
103
        struct Abort;
104
        impl Drop for Abort {
105
            fn drop(&mut self) {
106
                panic!();
107
            }
108
        }
109
        let _a = Abort;
110
        panic!("abort");
111
    }
112
}
113
114
#[inline(always)]
115
#[cfg(feature = "std")]
116
0
fn saturating_sub_usize_u64(a: usize, b: u64) -> usize {
117
    use core::convert::TryFrom;
118
0
    match usize::try_from(b) {
119
0
        Ok(b) => a.saturating_sub(b),
120
0
        Err(_) => 0,
121
    }
122
0
}
123
124
#[inline(always)]
125
#[cfg(feature = "std")]
126
0
fn min_u64_usize(a: u64, b: usize) -> usize {
127
    use core::convert::TryFrom;
128
0
    match usize::try_from(a) {
129
0
        Ok(a) => usize::min(a, b),
130
0
        Err(_) => b,
131
    }
132
0
}
133
134
/// Error type for the `try_get_` methods of [`Buf`].
135
/// Indicates that there were not enough remaining
136
/// bytes in the buffer while attempting
137
/// to get a value from a [`Buf`] with one
138
/// of the `try_get_` methods.
139
#[derive(Debug, PartialEq, Eq)]
140
pub struct TryGetError {
141
    /// The number of bytes necessary to get the value
142
    pub requested: usize,
143
144
    /// The number of bytes available in the buffer
145
    pub available: usize,
146
}
147
148
impl core::fmt::Display for TryGetError {
149
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
150
0
        write!(
151
0
            f,
152
0
            "Not enough bytes remaining in buffer to read value (requested {} but only {} available)",
153
0
            self.requested,
154
0
            self.available
155
0
        )
156
0
    }
157
}
158
159
#[cfg(feature = "std")]
160
impl std::error::Error for TryGetError {}
161
162
#[cfg(feature = "std")]
163
impl From<TryGetError> for std::io::Error {
164
0
    fn from(error: TryGetError) -> Self {
165
0
        std::io::Error::new(std::io::ErrorKind::Other, error)
166
0
    }
167
}
168
169
/// Panic with a nice error message.
170
#[cold]
171
0
fn panic_advance(error_info: &TryGetError) -> ! {
172
0
    panic!(
173
0
        "advance out of bounds: the len is {} but advancing by {}",
174
0
        error_info.available, error_info.requested
175
0
    );
176
}
177
178
#[cold]
179
0
fn panic_does_not_fit(size: usize, nbytes: usize) -> ! {
180
0
    panic!(
181
0
        "size too large: the integer type can fit {} bytes, but nbytes is {}",
182
0
        size, nbytes
183
0
    );
184
}
185
186
/// Precondition: dst >= original
187
///
188
/// The following line is equivalent to:
189
///
190
/// ```rust,ignore
191
/// self.ptr.as_ptr().offset_from(ptr) as usize;
192
/// ```
193
///
194
/// But due to min rust is 1.39 and it is only stabilized
195
/// in 1.47, we cannot use it.
196
#[inline]
197
2.23M
fn offset_from(dst: *const u8, original: *const u8) -> usize {
198
2.23M
    dst as usize - original as usize
199
2.23M
}