peekable 0.5.0

Buffered peek for `Read` and async readers (tokio, futures): inspect incoming bytes without consuming them. Useful for protocol detection, length-prefixed framing, and header inspection.
Documentation

Peekable reader and async reader, which enhance your network programming experience.

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 first N bytes, then heap (default with smallvec feature).
  • tinyvec::TinyVec<[u8; N]> — inline first N bytes, then heap (with tinyvec feature).

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.