continue_stream

A Swift-style AsyncIterator.Continuation-style channel for Rust.
This crate provides a lightweight, single-producer single-consumer (SPSC) channel designed specifically for bridging synchronous and asynchronous code. It's the streaming counterpart to the continue crate, optimized for sending multiple values over time rather than a single result.
Key Features
- Sync-to-async bridge: Synchronous senders, asynchronous receivers
- Buffered: Multiple items can be sent before the receiver polls
- Cancellation-aware: Both sides can detect when the other has been dropped
- Stream implementation: Receivers implement
futures::Streamfor ergonomic async iteration - Lightweight: No cloning overhead, optimized for single-producer single-consumer use
no_stdcompatible: Works in embedded and WASM environments withalloc
Design Philosophy
Like the continue crate:
- The send-side is synchronous, and the receive-side is asynchronous, as this crate is designed as a primitive used to bridge synchronous and asynchronous code.
- Cancellation is thoughtfully supported and considered in the design.
- The channel is a single-producer, single-consumer pair. Bring your own
Clone, or consider more complex solutions if you need multiple producers or consumers.
Unlike the continue crate:
- The channel is buffered, allowing the sender to send multiple items before the receiver polls.
- Dropping an unsent sender does not panic but instead gracefully terminates the stream by producing
Noneon the receiver.
Unlike more complex channel types:
- Avoiding
Clonesimplifies the problem and unlocks the potential for more efficient implementations. - Focus on bridging sync and async code makes threading behavior more defined and predictable.
Usage
Add this to your Cargo.toml:
[]
= "0.1.0"
For no_std environments (embedded, WASM):
[]
= { = "0.1.0", = false }
Platform Support
no_stdcompatible: Works without the standard library, only requiresalloc- Full functionality: All features including threading work in both
stdandno_stdenvironments
Examples
Basic Usage
use continuation;
let = ;
// Send from synchronous code
sender.send;
sender.send;
sender.send;
drop; // Signal completion
// Receive in async code
while let Some = receiver.receive.await
Using as a Stream
use continuation;
use StreamExt;
let = ;
// Send some messages
sender.send;
sender.send;
drop;
// Use Stream combinators
let messages: = receiver.collect.await;
assert_eq!;
Cross-thread Communication
use continuation;
use thread;
use Duration;
let = ;
// Spawn a thread that sends values
spawn;
// Receive values asynchronously
let mut count = 0;
while let Some = receiver.receive.await
assert_eq!;
Cancellation Detection
use continuation;
let = ;
// Drop the receiver to cancel
drop;
// Sender can detect cancellation
assert!;
API
The crate provides three main types:
continuation<T>() -> (Sender<T>, Receiver<T>)
Creates a new continuation channel, returning a sender-receiver pair.
Sender<T>
The sending half of a continuation channel. Allows synchronous code to send values to an asynchronous receiver.
send(item: T)- Sends a value through the channel (non-blocking)is_cancelled() -> bool- Checks if the receiver has been dropped
Receiver<T>
The receiving half of a continuation channel. Provides asynchronous access to values sent through a Sender.
receive() -> ReceiveFuture<T>- Receives a single value from the channelis_cancelled() -> bool- Checks if the sender has been dropped
Implements futures::Stream for ergonomic async iteration.
License
This project is licensed under the MIT or Apache-2.0 license, at your option.