rust / expert
Snippet
Manual Polling Pattern for Asynchronous Streams
Creating stream-like primitives in std Rust without futures crate involves returning Poll<Result<T, E>> to express readiness and operational status manually.
snippet.rs
rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
use std::task::{Context, Poll};pub struct RingStream<T> {buffer: Vec<T>,cursor: usize,}impl<T: Clone> RingStream<T> {pub fn new(items: Vec<T>) -> Self {Self { buffer: items, cursor: 0 }}pub fn poll_next_item(&mut self, _cx: &mut Context<'_>) -> Poll<Result<T, &'static str>> {if self.buffer.is_empty() {Poll::Ready(Err("Stream source buffer is empty"))} else {let item = self.buffer[self.cursor].clone();self.cursor = (self.cursor + 1) % self.buffer.len();Poll::Ready(Ok(item))}}}
Breakdown
1
pub struct RingStream<T> {
Encapsulates a cyclic item buffer with an internal reading cursor state.
2
pub fn poll_next_item(&mut self, _cx: &mut Context<'_>) -> Poll<Result<T, &'static str>>
Defines custom poll method returning Poll enum with Result item payload.
3
if self.buffer.is_empty() {
Evaluates buffer validity and returns Ready error status if stream cannot produce data.
4
self.cursor = (self.cursor + 1) % self.buffer.len();
Advances cursor position atomically within fixed circular boundaries.