Coverage Report

Created: 2024-12-17 06:15

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