qubit-io

Small stream I/O trait utilities for Rust

Rust CI Coverage Crates.io Rust License

Small stream I/O trait and extension utilities for Rust.

Overview

Qubit IO is focused on stream and byte I/O built on top of std::io. It does not try to become a filesystem abstraction layer. The crate provides reusable building blocks for code that reads, writes, seeks, buffers, encodes, decodes, limits, tees, counts, or compares byte streams.

Use this crate when you need:

For detailed usage, examples, and API selection guidance, see the User Guide. API reference documentation is available on docs.rs.

For local filesystem capabilities, see qubit-local-fs.

Installation

[dependencies]
qubit-io = "0.2"

Quick Example

use std::io::Cursor;

use qubit_io::{
    ReadExt,
    Streams,
    WriteSeekExt,
};

let mut input = Cursor::new(b"hello".to_vec());
let mut output = Vec::new();

Streams::copy(&mut input, &mut output)?;
assert_eq!(b"hello", output.as_slice());

let mut cursor = Cursor::new(vec![0; 8]);
cursor.write_all_at_preserving_position(2, b"rs")?;

let data = Cursor::new(b"bounded".to_vec()).read_to_end_limited(16)?;
assert_eq!(b"bounded", data.as_slice());

# Ok::<(), std::io::Error>(())

Main Capabilities

Object-Safe I/O Trait Combinations

qubit-io provides named composition traits that can be used as trait objects:

TraitCombinesTypical use
ReadSeekRead + Seekreadable random-access input
BufReadSeekBufRead + Seekbuffered random-access input
ReadWriteRead + Writeduplex stream or mutable buffer
WriteSeekWrite + Seekwritable random-access output
ReadWriteSeekRead + Write + Seekfully mutable random-access I/O object

These traits are useful when an API should accept &mut dyn ReadSeek instead of being generic over R: Read + Seek.

Extension Traits

The extension traits keep common low-level I/O patterns close to the standard library while avoiding repeated boilerplate:

Extension traitExamples
ReadExtread_exact_or_eof, discard_exact_or_eof, copy_to, read_to_end_limited, read_to_string_limited
BufReadExtread_until_limited, read_line_limited, discard_until_limited
SeekExtstream_size
ReadSeekExtpeek_exact_or_eof, read_exact_or_eof_at
WriteSeekExtwrite_all_at_preserving_position
BinaryReadExt / BinaryWriteExtfixed-width integer and floating-point scalar encoding
Leb128ReadExt / Leb128WriteExtunsigned and signed LEB128 integer encoding
ZigZagReadExt / ZigZagWriteExtZigZag-mapped signed integer encoding
StringReadExt / StringWriteExtlength-prefixed UTF-8 strings

Streams Namespace

Streams contains stream-level associated functions:

MethodPurpose
copydelegates to std::io::copy
copy_at_mostcopies no more than a specified number of bytes
copy_to_end_limitedcopies only if EOF is reached within a size limit
content_eqcompares two readable streams for byte equality
compare_contentlexicographically compares two readable streams

Wrappers

Wrapper types make stream behavior part of the type instead of a one-off call:

WrapperPurpose
CountingReader, CountingWritercount successfully read or written bytes
LimitReader, LimitWriterenforce read or write byte budgets
TeeReader, TeeWriterduplicate data to a branch writer
ChecksumReader, ChecksumWriterupdate caller-provided checksum state while reading or writing
PositionGuardrestore a seek position on drop unless dismissed

Codec Wrappers

Callers who prefer reader/writer objects over extension-method calls can use root-level codec wrappers:

WrapperPurpose
BinaryReader, BinaryWriterfixed-width scalar encoding and decoding
Leb128Reader, Leb128WriterLEB128 encoding and decoding
ZigZagReader, ZigZagWriterZigZag over unsigned LEB128 payloads

Prelude

qubit_io::prelude re-exports the method-providing extension traits and the object-safe composition traits. It intentionally does not re-export wrapper types or concrete namespaces.

use qubit_io::prelude::*;

Crate Boundary

qubit-io is intentionally limited to stream and byte I/O. It does not expose local path helpers, temporary files, directory copy helpers, directory cleanup, or atomic file writes. For local filesystem capabilities, see qubit-local-fs.

Runtime Dependencies

This crate depends only on the Rust standard library at runtime.

Testing & Code Coverage

This project maintains test coverage for the stream traits, extension methods, codec helpers, and wrapper types.

Running Tests

# Run all tests
cargo test

# Run with coverage report
./coverage.sh

# Generate text format report
./coverage.sh text

# Run CI checks (format, clippy, test, coverage, audit)
./ci-check.sh

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

Author

Haixing Hu

---

Repository: https://github.com/qubit-ltd/rs-io