reading-liner
A Rust crate for streaming construction of line/column indices over text sources.
It enables on-the-fly (one-pass) mapping from byte offsets to (line, column) locations while reading from a stream (e.g. a file), without requiring the entire input to be loaded into memory.
It provides a Stream reader which can convert between byte offset and line-column numbers.
Support any type which implements std::io::Read.
The whole design is based on an Index,
which is composed of line information to convert between byte offsets and line-column locations.
One perticular usage is to use the Stream as a builder of Index or
you can also use it when lazily reading and convert locations at the same time.
This lib should be used at low-level abstraction.
📍 Features
- Offset → (line, column) mapping
- True streaming support (no full file buffering required)
- Consistent with in-memory indexing
- Single-pass construction
- Designed to integrate with parsers and error reporting tools (e.g. codespan_reporting)
🚀 Motivation
Most existing approaches follow this pattern:
let src = read_to_string?;
let index = build_index;
❌ This has several drawbacks:
- Requires loading the entire file into memory
- Not suitable for streaming or large inputs
- Forces a separation between IO and indexing (often multiple passes)
✅ This crate takes a different approach
It builds the index as the data is being read, enabling:
- Parsing directly from a stream
- Accurate location tracking without a second pass
- Reduced memory footprint for large files
🎯 Use Cases
- Compilers and interpreters
- Incremental / streaming parsers
- Large file processing
- Custom diagnostic tools
- Language tooling (LSP, linters, etc.)
📄 Documentation
The API is documented at https://docs.rs/reading-liner.
📦 Examples
Load and build index
use ;
use Read;
use ;
Build index while loading
use ;
use Read;
use ;
For more examples, please refer to tests