Qubit IO
Byte-stream buffering and small std::io trait utilities for Rust.
Overview
qubit-io provides:
- byte-oriented buffering primitives:
Buffer,BufferedByteInput, andBufferedByteOutput; - object-safe composition traits such as
ReadSeek,ReadWrite, andReadWriteSeek; - extension traits for recurring
Read,BufRead,Seek,Read + Seek,Write, andWrite + Seekpatterns; Streamsutility functions for copy and content comparison operations;- lightweight reader and writer wrappers such as
CountingReader,LimitReader,PositionGuard,TeeReader, and checksum wrappers.
Binary scalar, LEB128, and ZigZag codecs are no longer part of this crate. Use
qubit-codec-binary for buffer-level binary codecs and qubit-io-binary for
binary stream readers, writers, and extension traits.
Detailed usage is documented in the user guide. API reference documentation is available on docs.rs.
Design Goals
- Generic I/O Only: keep this crate focused on reusable
std::iohelpers. - Byte-Level Buffering: provide efficient byte buffers without embedding binary codec, text codec, or record-format knowledge.
- Explicit Low-Level Contracts: expose hot-path APIs such as
Bufferand unchecked range helpers with clear caller responsibilities. - Object-Safe Composition: make common trait combinations easy to name and pass around.
- Predictable Extension Traits: provide recurring read, write, seek, and copy patterns without hiding allocation or error behavior.
- Layer Separation: keep binary and text codec stream adapters in sibling crates.
- Small Dependency Graph: provide useful I/O tools without runtime dependencies.
Features
Buffered Byte I/O
Buffer<T>: low-level position/limit storage with a readable window and spare tail capacity.BufferedByteInput: buffered byte input overRead, with unread-window inspection,BufReadsupport, count-aware refilling, logical seeking,into_parts, and indexed unchecked reads for validated output ranges.BufferedByteOutput: buffered byte output overWrite, with spare-window access, checked and unchecked advancing, explicit flushing, non-flushinginto_parts, seeking, and large-write bypass paths.DEFAULT_BUFFER_CAPACITY: shared default capacity for byte input and output buffering.
Composition Traits
ReadSeek: namesRead + Seek.BufReadSeek: namesBufRead + Seek.ReadWrite: namesRead + Write.ReadWriteSeek: namesRead + Write + Seek.WriteSeek: namesWrite + Seek.
Extension Traits
ReadExt: exact reads, partial EOF reads, limited reads, and copy helpers.BufReadExt: bounded line and delimiter reads.SeekExt: stream size helpers that preserve position.ReadSeekExt: peek/read-at helpers that restore position.WriteExt: unchecked write helpers for validated ranges.WriteSeekExt: write-at helpers that preserve position.
Utility Functions and Wrappers
Streams: copy, bounded copy, equality, and lexicographic comparison.- Counting wrappers:
CountingReaderandCountingWriter. - Limit wrappers:
LimitReaderandLimitWriter. - Tee wrappers:
TeeReaderandTeeWriter. - Checksum wrappers:
ChecksumReaderandChecksumWriter. - Position guard:
PositionGuardrestores stream position on drop unless dismissed.
Documentation
Installation
Add this to your Cargo.toml:
[]
= "0.7"
Quick Start
use ;
use ;
let mut input = new;
let mut prefix = ;
let read = input.read_exact_or_eof?;
assert_eq!;
assert_eq!;
let mut source = new;
let mut output = Vecnew;
let copied = copy_at_most?;
assert_eq!;
assert_eq!;
let mut buffered_input = with_capacity;
buffered_input.ensure_available?;
assert_eq!;
unsafe
let mut buffered_output =
with_capacity;
buffered_output.ensure_spare_capacity?;
buffered_output.spare_buffer_mut.copy_from_slice;
unsafe
buffered_output.flush?;
let = buffered_output.into_parts;
assert!;
assert_eq!;
# Ok::
API Reference
Trait Aliases
| Trait | Equivalent Bounds |
|---|---|
ReadSeek |
Read + Seek |
BufReadSeek |
BufRead + Seek |
ReadWrite |
Read + Write |
ReadWriteSeek |
Read + Write + Seek |
WriteSeek |
Write + Seek |
Utility Types
| Type | Purpose |
|---|---|
Buffer |
Low-level position/limit storage for hot-path buffering |
BufferedByteInput |
Buffered byte input over a Read source |
BufferedByteOutput |
Buffered byte output over a Write sink |
Streams |
Static helpers for copying and comparing streams |
CountingReader / CountingWriter |
Count successful bytes read or written |
LimitReader / LimitWriter |
Cap bytes read or written through a wrapper |
TeeReader / TeeWriter |
Mirror bytes into a secondary sink |
ChecksumReader / ChecksumWriter |
Feed successful bytes into a caller-provided hasher |
PositionGuard |
Restore a seek position unless explicitly dismissed |
Constants
| Constant | Purpose |
|---|---|
DEFAULT_BUFFER_CAPACITY |
Shared default capacity for buffered byte input and output |
Crate Split
The codec and stream stack is intentionally split:
qubit-codec: core byte order, codec, transcoder, encoder, and decoder traits;qubit-codec-binary: buffer-level binary, LEB128, and ZigZag codecs;qubit-io: genericstd::iohelpers;qubit-io-binary: binary stream readers, writers, and extension traits;qubit-codec-textandqubit-io-text: text codecs and text stream adapters.
Performance Considerations
Most helpers operate directly on caller-provided buffers and delegate to the
underlying Read, Write, or Seek implementation. Wrapper types avoid hidden
allocation; any buffering policy remains explicit at the call site.
Buffer<T>, BufferedByteInput::unread_raw_parts, and
BufferedByteOutput::spare_raw_parts_mut are low-level APIs for callers that
have already validated ranges. They are intended for hot paths such as binary
and text stream adapters where avoiding repeated slicing and bounds checks
matters. Safe wrapper methods remain available for general-purpose use.
Testing & Code Coverage
This project keeps generic I/O behavior covered by integration tests under
tests/.
Running Tests
# Run all tests
# Run with coverage report
# Generate text format report
# Align code with CI requirements
# Run CI checks (format, clippy, test, coverage, audit)
RS_CI_SKIP_TOOLCHAIN_UPDATE=1
Dependencies
qubit-io has no runtime dependencies.
License
Copyright (c) 2026. Haixing Hu.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
See LICENSE for the full license text.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Guidelines
- Keep this crate generic and independent of concrete codec formats.
- Maintain deterministic tests for I/O edge cases.
- Document public APIs and error behavior.
- Ensure all checks pass before submitting a PR.
Author
Haixing Hu
Related Projects
More Rust libraries from Qubit are available under the qubit-ltd GitHub organization.
Repository: https://github.com/qubit-ltd/rs-io