Skip to content

Commit 91c4092

Browse files
committed
feat: add interval_stream helper
1 parent 0f2d8ef commit 91c4092

File tree

6 files changed

+194
-5
lines changed

6 files changed

+194
-5
lines changed

Cargo.lock

Lines changed: 112 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "toolbox"
3-
version = "0.1.0"
3+
version = "0.2.0"
44
authors = ["Oliver Chalk"]
55
edition = "2021"
66
readme = "README.md"
@@ -14,13 +14,15 @@ disallowed_methods = "warn"
1414

1515
[features]
1616
default = []
17-
tokio = ["dep:tokio"]
17+
named_task = ["tokio/rt"]
18+
interval_stream = ["tokio/time", "dep:futures"]
1819
tracing = ["dep:const_format", "dep:tracing", "dep:tracing-appender", "dep:tracing-subscriber"]
1920
version = ["dep:const_format"]
2021

2122
[dependencies]
2223
const_format = { version = "0.2.32", optional = true }
23-
tokio = { version = "1.0", features = ["rt"], optional = true }
24+
futures = { version = "0.3.31", optional = true }
25+
tokio = { version = "1.0", optional = true }
2426
tracing = { version = "0.1.40", optional = true }
2527
tracing-appender = { version = "0.2.3", optional = true }
2628
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "json"], optional = true }

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod fs;
2-
#[cfg(feature = "tokio")]
2+
#[cfg(any(feature = "named_task", feature = "interval_stream"))]
33
pub mod tokio;
44
#[cfg(feature = "tracing")]
55
pub mod tracing;

src/tokio/interval_stream.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use std::future::Future;
2+
use std::pin::pin;
3+
use std::task::Poll;
4+
5+
use futures::{ready, Stream};
6+
7+
pub struct IntervalStream<Poll, Fut>
8+
where
9+
Poll: Fn() -> Fut + Unpin,
10+
Fut: Unpin,
11+
{
12+
interval: tokio::time::Interval,
13+
poll: Poll,
14+
15+
in_progress: Option<Fut>,
16+
}
17+
18+
impl<Poll, Fut, Output> IntervalStream<Poll, Fut>
19+
where
20+
Poll: Fn() -> Fut + Unpin,
21+
Fut: Future<Output = Output> + Unpin,
22+
{
23+
pub fn new(interval: tokio::time::Interval, poll: Poll) -> Self {
24+
IntervalStream { interval, poll, in_progress: None }
25+
}
26+
}
27+
28+
impl<PollFn, Fut, Output> Stream for IntervalStream<PollFn, Fut>
29+
where
30+
PollFn: Fn() -> Fut + Unpin,
31+
Fut: Future<Output = Output> + Unpin,
32+
{
33+
type Item = Output;
34+
35+
fn poll_next(
36+
self: std::pin::Pin<&mut Self>,
37+
cx: &mut std::task::Context<'_>,
38+
) -> std::task::Poll<Option<Self::Item>> {
39+
let this = self.get_mut();
40+
41+
// Poll the current future if one already exists.
42+
if let Some(fut) = &mut this.in_progress {
43+
let output = ready!(pin!(fut).poll(cx));
44+
this.in_progress = None;
45+
46+
return Poll::Ready(Some(output));
47+
}
48+
49+
// Poll the interval to see if we should create a new future.
50+
ready!(this.interval.poll_tick(cx));
51+
52+
// Create a new future.
53+
let mut fut = (this.poll)();
54+
55+
// Poll the future.
56+
let pinned = pin!(&mut fut);
57+
let poll = pinned.poll(cx);
58+
match poll {
59+
Poll::Ready(output) => Poll::Ready(Some(output)),
60+
Poll::Pending => {
61+
this.in_progress = Some(fut);
62+
63+
Poll::Pending
64+
}
65+
}
66+
}
67+
}

src/tokio/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#[cfg(feature = "interval_stream")]
2+
mod interval_stream;
3+
#[cfg(feature = "named_task")]
4+
mod named_task;
5+
6+
#[cfg(feature = "interval_stream")]
7+
pub use interval_stream::*;
8+
#[cfg(feature = "named_task")]
9+
pub use named_task::*;
File renamed without changes.

0 commit comments

Comments
 (0)