Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# Gat Lending Iterator

A library for lending iterators using Generic Associated Types (GATs). Lending iterators allow items to borrow from `&mut self`, enabling patterns like iterating over windows of elements with references. **Work in progress**.
A library for lending iterators using Generic Associated Types (GATs). **Work in progress**.

[![Crates.io](https://img.shields.io/crates/v/gat-lending-iterator.svg)](https://crates.io/crates/gat-lending-iterator)
[![Documentation](https://docs.rs/gat-lending-iterator/badge.svg)](https://docs.rs/gat-lending-iterator)

## What are Lending Iterators?

**Lending iterators** yield items that borrow from the iterator itself. Standard Rust iterators cannot do this—each item must be independent. Using [Generic Associated Types](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html), lending iterators enable efficient patterns like overlapping windows without cloning:

```rust
trait LendingIterator {
type Item<'a> where Self: 'a;
fn next(&mut self) -> Option<Self::Item<'_>>;
}
```

This allows items to have lifetimes tied to `&mut self`, enabling iteration over mutable views and streaming parsers without buffering.

## Example

```rust
Expand Down
36 changes: 24 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
//! This crate uses generic associated types to supply an iterator trait
//! that allows the items to \[mutably\] borrow from the iterator.
//! See [the GAT anouncement](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html)
//! # Lending Iterators with Generic Associated Types
//!
//! Most `Iterator` methods can work as is on `LendingIterator`s, but some wouldn't make sense.
//! Basically any method that needs to look at more than one element at once isn't possible, or needs to be modified.
//! A **lending iterator** yields items that borrow from the iterator itself, unlike standard
//! `Iterator` where each item must be independent. This is enabled by [Generic Associated Types
//! (GATs)](https://blog.rust-lang.org/2022/10/28/gats-stabilization.html):
//!
//! Some `LendingIterator` methods *may* return something that can act as an `Iterator`.
//! For example `cloned`, or `map`, when the function passed to it
//! returns a value that isn't tied to the lifetime of its input.
//! In these cases, my design choice was to conditionally implement `IntoIterator` for the adapter.
//! ```ignore
//! trait LendingIterator {
//! type Item<'a> where Self: 'a;
//! fn next(&mut self) -> Option<Self::Item<'_>>;
//! }
//! ```
//!
//! ## Why Lending Iterators?
//!
//! Standard iterators cannot return items that borrow from `&mut self` due to lifetime constraints.
//! Lending iterators solve this, enabling patterns like overlapping mutable windows without cloning
//! or streaming parsers that reuse internal buffers.
//!
//! ## API Design
//!
//! Most `Iterator` methods work on `LendingIterator`, except those requiring multiple items
//! simultaneously (e.g., `collect`, `peekable`). Some methods like `map` and `cloned` conditionally
//! implement `IntoIterator` when the returned value doesn't borrow from input.
//!
//! This crate also provides an extension trait `ToLendingIterator: Iterator` for iterators
//! that allows turning them into lending iterators (over windows of elements).
//! There may be more methods added to this trait in the future.
//! This crate provides `ToLendingIterator` to convert standard iterators into lending iterators,
//! enabling methods like `windows()` and `windows_mut()`.
//!
//! # Examples
//!
Expand Down