#io #traits #bounds #static #reader #seek #reader-writer

flexible-io

Wraps values such that dyn-safe IO traits need not appear as static bounds

6 releases (3 breaking)

0.4.0 Oct 19, 2024
0.3.1 Aug 26, 2024
0.2.0 Dec 7, 2023
0.1.1 Dec 3, 2023
0.1.0 Nov 16, 2023

#1262 in Rust patterns

EUPL-1.2

29KB
441 lines

Flexible IO

Packs a reader or writer with its io-trait implementations, allowing the omission of the traits in the static trait bounds.

The motivation of this is enabling APIs in which use of a reader (or writer) can be optimized in case of it being buffered, but it's not required for correct functioning. Or, an API where the Seek requirement is only determined at runtime, such as when a portion of the functionality does not depend on it, and an error should be returned.

The crate implements, as a proof of concept, a reader which can optionally Seek or BufRead; and a writer which can optionally Seek. Its up to a caller to provide the traits by calling setter methods, in a local scope where the traits are statically shown to be implemented.

Usage

use flexible_io::Reader;
fn read_from<R>(reader: Reader<R>) {
    if let Some(seekable) = file.as_seek_mut() {
        with_seek_strategy(reader);
    } else {
        with_read_strategy(reader);
    }
}

Known issues

Due to lifetime issues, it is not possible to preserve the knowledge of a trait being implemented. That is, each conversion from Reader to a concrete value of either type &mut dyn {Read,BufRead,Seek} mutably borrows the whole reader. Therefore you can't have to such references at the same time. As a workaround, unwrap the Option returned from as_* methods where appropriate.

No runtime deps

Features