Expand description
Peekable
§Introduction
In network programming, applications frequently need to inspect incoming data before fully consuming it. Common patterns include reading message type indicators, parsing length-prefixed headers, or implementing protocol detection. However, current peek solutions have significant limitations:
System call-based approaches like std::net::TcpStream::peek and tokio::net::TcpStream::peek directly invoke system calls for each peek operation. While functionally correct, these methods impose unnecessary overhead since system calls are expensive operations that should be minimized in performance-critical network code.
Buffered reader workarounds involve wrapping streams with BufReader and using methods like fill_buf() and buffer() to simulate peeking behavior. This approach is cumbersome and inefficient—BufReader uses a heap-allocated Vec<u8> as its internal buffer, which is overkill for typical peek scenarios where you only need to examine a few bytes (often 1-8 bytes for headers or type tags).
peekable provides a better solution: a lightweight, efficient peek implementation for both synchronous and asynchronous readers.
§Installation
-
Std
[dependencies] peekable = "0.5" -
Tokio I/O
[dependencies] peekable = { version = "0.5", features = ["tokio"] } -
Futures I/O
[dependencies] peekable = { version = "0.5", features = ["future"] }
§Feature flags
| Feature | Default | Purpose |
|---|---|---|
smallvec | yes | Use SmallVec<[u8; 64]> as the default peek buffer (avoids a heap allocation for typical peek sizes). |
future | no | future::AsyncPeekable for futures_util::io::AsyncRead. |
tokio | no | tokio::AsyncPeekable for tokio::io::AsyncRead (also enables peek_buf for bytes::BufMut). |
tinyvec | no | Adds a Buffer impl for tinyvec::TinyVec so it can be used as a custom backend. |
§Buffer backends
Peekable<R, B> and AsyncPeekable<R, B> are generic over the
backing storage B. Any type that implements the peekable::buffer::Buffer
trait works. Bundled implementations:
Vec<u8>— heap-only.smallvec::SmallVec<[u8; N]>— inline firstNbytes, then heap (default withsmallvecfeature).tinyvec::TinyVec<[u8; N]>— inline firstNbytes, then heap (withtinyvecfeature).
Pick a backend with peekable_with_buffer::<B>() /
peekable_with_capacity_and_buffer::<B>(cap). You can also implement
Buffer for your own type if you need a custom backing store.
§Examples
See examples for more details.
§MSRV
The declared crate-wide minimum supported Rust version is 1.71.0.
This is dictated by the current tokio minimum, which the optional
tokio feature pulls in. While the crate would otherwise compile on
1.60 (due to the dep: feature prefix used in Cargo.toml), Cargo
cannot currently express feature-specific MSRVs, so users must use
Rust 1.71.0 or newer regardless of whether tokio is enabled. MSRV
bumps will be considered a breaking change and require a minor version
bump pre-1.0 (major post-1.0).
§License
peekable is under the terms of both the MIT license and the
Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT for details.
Copyright (c) 2026 Al Liu.
Modules§
- buffer
- The generic buffer trait used by the
PeekableandAsyncPeekable. - future
future - Asynchronous peek I/O
- tokio
tokio - Traits, helpers, and type definitions for asynchronous peekable I/O functionality.
Macros§
- ready
tokioorfuture - Extracts the successful type of a
Poll<T>.