try-next

Minimal traits for synchronous, fallible, pull-based item sources.
Overview
This module defines three related traits:
- [
TryNext] — a context-free, fallible producer of items, - [
TryNextWithContext<C>] — a context-aware variant that allows the caller to supply mutable external state on each iteration step. - [
IterInput<I>] — an input adapter that wraps any iterator and providesTryNextandTryNextWithContext<C>interface, automatically fusing the iterator - [
std::io::BufReader<R>] — implementations of theTryNextandTryNextWithContext<C>traits for anyBufReader<R>whereR: Read.
Traits [TryNext] and [TryNextWithContext<C>] follow the same basic pattern:
they represent a source that can attempt to produce the next item, which may
succeed, fail, or signal the end of the sequence.
Core idea
Each try_next* method call returns a [Result] with three possible outcomes:
Ok(Some(item))— a successfully produced item,Ok(None)— no more items are available (the source is exhausted),Err(error)— an error occurred while trying to produce the next item.
These traits are synchronous — each call blocks until a result is ready.
They are suitable for ordinary blocking or CPU-bound producers such as parsers,
generators, or readers. For asynchronous, non-blocking sources, use
futures::TryStream.
[TryNext]
The simplest case: a self-contained, fallible producer that doesn’t depend on any external context.
use TryNext;
let mut src = Demo ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
[TryNextWithContext<C>]
A generalization of [TryNext] that allows each call to [try_next_with_context]
to receive a mutable reference to a caller-supplied context.
The context can hold shared mutable state, configuration data, or external resources such as file handles, buffers, or clients. This pattern is useful when the producer needs external help or coordination to produce the next item, while keeping the trait itself simple and generic.
use TryNextWithContext;
;
let mut producer = Producer;
let mut ctx = Ctx ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
[IterInput<I>]
A simple [TryNextWithContext] adapter for ordinary Rust iterators.
IterInput wraps any [Iterator] and exposes it as a
[TryNextWithContext<C>] producer that never fails and ignores the provided context.
Internally, the iterator is automatically fused — once it yields None,
all subsequent calls also return None.
This is useful for integrating plain iterators into APIs or components that expect a context-aware, fallible producer, without changing their semantics.
Example
use TryNextWithContext;
use IterInput;
;
let data = ;
let mut input = from;
let mut ctx = DummyCtx;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!; // fused
Notes
- The
Ctype parameter exists for trait compatibility but is not used. - The error type is always [
Infallible], as the wrapped iterator cannot fail. - Ideal for testing or bridging APIs that use [
TryNextWithContext<C>] but only need to pull from a fixed iterator.
Optional stats type S
Both [TryNext] and [TryNextWithContext<C>] accept an optional generic parameter
S: Default + Copy, representing a lightweight statistics snapshot.
By default, S = (), and calling stats() simply returns ().
Implementors may define custom S types to expose simple metrics such as iteration counts, processing progress, or internal state summaries.
use TryNext;
[TryNext] and [TryNextWithContext<C>] for BufReader<R>
try-next now includes built-in support for [std::io::BufReader] as a fallible, byte-oriented source.
This allows you to iterate over bytes from any Read stream — including files, sockets, or standard input — using the same familiar trait methods.
Example
use ;
use TryNext;
Highlights
- Works with any
R: Read - Reads one
u8at a time, returningOk(None)at EOF - Propagates I/O errors automatically
Why not just Iterator<Item = Result<T, E>>?
You can use an Iterator of Results — and for many cases you should.
TryNext exists for scenarios where:
- You don’t need or want the entire iterator API surface,
- You want a blocking, stepwise producer that can fail (e.g., parser, file reader),
- You’d like an API closer to I/O traits like
ReadorBufReadwith fallible semantics.
It’s deliberately small and easy to wrap or adapt into an iterator when needed.
Features
- 🦀 Zero dependencies
- ⚙️ Simple and explicit
Result<Option<T>, E>semantics - 🧩 Works in
no_stdenvironments (optional, if you don’t depend onstd::error::Error) - 📚 Documented and unit-tested
Installation
Add this line to your Cargo.toml:
[]
= "0.4"
Then import the trait:
use ;
Design notes
- Both traits are deliberately minimal: they define no combinators or adapters. Their purpose is to provide a simple, low-level interface for fallible, stepwise data production.
TryNextWithContext<C>can often serve as a building block for adapters that integrate external state or resources.- These traits are a good fit for incremental or stateful producers such as parsers, lexers, tokenizers, and other components that advance in discrete steps while potentially failing mid-stream.
Related Work
-
std::io::Read—
The standard synchronous, fallible, pull-based trait for reading bytes.
TryNextis conceptually similar but works with generic items instead of raw byte buffers. -
Iterator<Item = Result<T, E>>—
The idiomatic pattern for representing fallible iteration in the standard library.
Works well for most use cases but couples error handling with the iterator interface. -
fallible-iterator—
A rich abstraction for fallible iteration, including combinators and adapters.
Heavier thanTryNext, but feature-complete if you need iterator-like utilities. -
fallible-streaming-iterator—
Similar tofallible-iteratorbut optimized for borrowing streams, avoiding allocations. -
futures::TryStream—
The asynchronous equivalent of this pattern.
Definestry_poll_nextreturningPoll<Option<Result<T, E>>>for non-blocking sources.
License
Released under the terms of the GNU Lesser General Public License, version 3.0 or (at your option) any later version (LGPL-3.0-or-later).
Contribution
Contributions are welcome!
Unless explicitly stated otherwise, any contribution intentionally submitted for inclusion in try-next by you shall be licensed as above, without any additional terms or conditions.
Author
Copyright (c) 2005–2025 IKH Software, Inc.