Coverage Report

Created: 2025-11-16 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/src/lib.rs
Line
Count
Source
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
    #[cfg(feature = "std")]
97
    {
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
88.9M
fn saturating_sub_usize_u64(a: usize, b: u64) -> usize {
117
88.9M
    match usize::try_from(b) {
118
88.9M
        Ok(b) => a.saturating_sub(b),
119
0
        Err(_) => 0,
120
    }
121
88.9M
}
122
123
#[inline(always)]
124
#[cfg(feature = "std")]
125
38.4M
fn min_u64_usize(a: u64, b: usize) -> usize {
126
38.4M
    match usize::try_from(a) {
127
38.4M
        Ok(a) => usize::min(a, b),
128
0
        Err(_) => b,
129
    }
130
38.4M
}
131
132
/// Error type for the `try_get_` methods of [`Buf`].
133
/// Indicates that there were not enough remaining
134
/// bytes in the buffer while attempting
135
/// to get a value from a [`Buf`] with one
136
/// of the `try_get_` methods.
137
#[derive(Debug, PartialEq, Eq)]
138
pub struct TryGetError {
139
    /// The number of bytes necessary to get the value
140
    pub requested: usize,
141
142
    /// The number of bytes available in the buffer
143
    pub available: usize,
144
}
145
146
impl core::fmt::Display for TryGetError {
147
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
148
0
        write!(
149
0
            f,
150
0
            "Not enough bytes remaining in buffer to read value (requested {} but only {} available)",
151
            self.requested,
152
            self.available
153
        )
154
0
    }
155
}
156
157
#[cfg(feature = "std")]
158
impl std::error::Error for TryGetError {}
159
160
#[cfg(feature = "std")]
161
impl From<TryGetError> for std::io::Error {
162
0
    fn from(error: TryGetError) -> Self {
163
0
        std::io::Error::new(std::io::ErrorKind::Other, error)
164
0
    }
165
}
166
167
/// Panic with a nice error message.
168
#[cold]
169
0
fn panic_advance(error_info: &TryGetError) -> ! {
170
0
    panic!(
171
0
        "advance out of bounds: the len is {} but advancing by {}",
172
        error_info.available, error_info.requested
173
    );
174
}
175
176
#[cold]
177
0
fn panic_does_not_fit(size: usize, nbytes: usize) -> ! {
178
0
    panic!(
179
0
        "size too large: the integer type can fit {} bytes, but nbytes is {}",
180
        size, nbytes
181
    );
182
}