fluxion_stream_time/
lib.rs

1// Copyright 2025 Umberto Gotti <umberto.gotti@umbertogotti.dev>
2// Licensed under the Apache License, Version 2.0
3// http://www.apache.org/licenses/LICENSE-2.0
4
5//! Time-based operators for streams with runtime-agnostic timer abstraction.
6//!
7//! This crate provides time-based operators for delaying, debouncing, throttling, sampling,
8//! and timeout handling of stream emissions. Operators work with any async runtime through
9//! the `Timer` trait abstraction.
10//!
11//! # Overview
12//!
13//! - **`Timer` trait** - Runtime-agnostic timer abstraction
14//! - **`InstantTimestamped<T, TM>`** - Wraps a value with a Timer's Instant timestamp
15//! - **`DelayExt`** - Extension trait for `.delay(duration, timer)`
16//! - **`DebounceExt`** - Extension trait for `.debounce(duration, timer)`
17//! - **`ThrottleExt`** - Extension trait for `.throttle(duration, timer)`
18//! - **`SampleExt`** - Extension trait for `.sample(duration, timer)`
19//! - **`TimeoutExt`** - Extension trait for `.timeout(duration, timer)`
20//!
21//! # Runtime Support
22//!
23//! Enable runtime-specific features in your `Cargo.toml`:
24//! - `runtime-tokio` (default) - Tokio runtime support with `TokioTimer`
25//! - `runtime-smol` - smol runtime support with `SmolTimer`
26//! - `runtime-wasm` - WebAssembly support with `WasmTimer`
27//! - `runtime-embassy` - Embassy (embedded) runtime support with `EmbassyTimerImpl` (no_std)
28//! - `runtime-async-std` - async-std runtime ⚠️ **DEPRECATED** (unmaintained, RUSTSEC-2025-0052)
29//!
30//! ⚠️ **Note**: async-std is discontinued. Use tokio or smol for new projects.
31//!
32//! # Example
33//!
34//! ```rust,no_run
35//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
36//! use fluxion_stream_time::{DebounceExt, DelayExt, TokioTimestamped};
37//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
38//! use fluxion_runtime::impls::tokio::TokioTimer;
39//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
40//! use fluxion_runtime::timer::Timer;
41//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
42//! use fluxion_core::StreamItem;
43//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
44//! use futures::stream::StreamExt;
45//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
46//! use std::time::Duration;
47//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
48//! use futures::channel::mpsc;
49//!
50//! # #[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
51//! # async fn example() {
52//! let (tx, rx) = mpsc::unbounded::<TokioTimestamped<i32>>();
53//! let timer = TokioTimer;
54//!
55//! // Delay all emissions by 100ms (convenience method)
56//! let delayed = rx
57//!     .map(StreamItem::Value)
58//!     .delay(Duration::from_millis(100));
59//!
60//! tx.unbounded_send(TokioTimestamped::new(42, timer.now())).unwrap();
61//! tx.unbounded_send(TokioTimestamped::new(100, timer.now())).unwrap();
62//!
63//! // Or debounce with convenience method (no timer parameter needed)
64//! # let (tx, rx) = mpsc::unbounded::<TokioTimestamped<i32>>();
65//! let debounced = rx
66//!     .map(StreamItem::Value)
67//!     .debounce(Duration::from_millis(100));
68//! # }
69//! # #[cfg(not(all(feature = "runtime-tokio", not(target_arch = "wasm32"))))]
70//! # fn example() {}
71//! ```
72
73#![cfg_attr(not(feature = "std"), no_std)]
74
75#[cfg(not(feature = "std"))]
76extern crate alloc;
77
78#[cfg(any(
79    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
80    feature = "runtime-smol",
81    feature = "runtime-async-std",
82    feature = "runtime-embassy",
83    feature = "runtime-wasm"
84))]
85mod debounce;
86#[cfg(any(
87    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
88    feature = "runtime-smol",
89    feature = "runtime-async-std",
90    feature = "runtime-embassy",
91    feature = "runtime-wasm"
92))]
93mod throttle;
94
95#[cfg(any(
96    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
97    feature = "runtime-smol",
98    feature = "runtime-async-std",
99    feature = "runtime-embassy",
100    feature = "runtime-wasm"
101))]
102mod delay;
103mod instant_timestamped;
104
105#[cfg(any(
106    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
107    feature = "runtime-smol",
108    feature = "runtime-async-std",
109    feature = "runtime-embassy",
110    feature = "runtime-wasm"
111))]
112mod sample;
113#[cfg(any(
114    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
115    feature = "runtime-smol",
116    feature = "runtime-async-std",
117    feature = "runtime-embassy",
118    feature = "runtime-wasm"
119))]
120mod timeout;
121
122#[cfg(any(
123    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
124    feature = "runtime-smol",
125    feature = "runtime-async-std",
126    feature = "runtime-embassy",
127    feature = "runtime-wasm"
128))]
129pub use debounce::DebounceExt;
130#[cfg(any(
131    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
132    feature = "runtime-smol",
133    feature = "runtime-async-std",
134    feature = "runtime-embassy",
135    feature = "runtime-wasm"
136))]
137pub use throttle::ThrottleExt;
138
139#[cfg(any(
140    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
141    feature = "runtime-smol",
142    feature = "runtime-async-std",
143    feature = "runtime-embassy",
144    feature = "runtime-wasm"
145))]
146pub use delay::DelayExt;
147pub use instant_timestamped::InstantTimestamped;
148#[cfg(any(
149    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
150    feature = "runtime-smol",
151    feature = "runtime-async-std",
152    feature = "runtime-embassy",
153    feature = "runtime-wasm"
154))]
155pub use sample::SampleExt;
156#[cfg(any(
157    all(feature = "runtime-tokio", not(target_arch = "wasm32")),
158    feature = "runtime-smol",
159    feature = "runtime-async-std",
160    feature = "runtime-embassy",
161    feature = "runtime-wasm"
162))]
163pub use timeout::TimeoutExt;
164
165#[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
166pub use fluxion_runtime::impls::tokio::TokioRuntime;
167
168#[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
169pub type TokioTimestamped<T> = InstantTimestamped<T, TokioRuntime>;
170
171#[cfg(all(feature = "runtime-async-std", not(target_arch = "wasm32")))]
172pub use fluxion_runtime::impls::async_std::AsyncStdRuntime;
173
174#[cfg(all(feature = "runtime-async-std", not(target_arch = "wasm32")))]
175pub type AsyncStdTimestamped<T> = InstantTimestamped<T, AsyncStdRuntime>;
176
177#[cfg(all(feature = "runtime-smol", not(target_arch = "wasm32")))]
178pub use fluxion_runtime::impls::smol::SmolRuntime;
179
180#[cfg(all(feature = "runtime-smol", not(target_arch = "wasm32")))]
181pub type SmolTimestamped<T> = InstantTimestamped<T, SmolRuntime>;
182
183#[cfg(all(
184    not(feature = "runtime-tokio"),
185    not(feature = "runtime-smol"),
186    not(feature = "runtime-async-std"),
187    not(feature = "runtime-embassy"),
188    feature = "runtime-wasm"
189))]
190pub use fluxion_runtime::impls::wasm::WasmRuntime;
191
192#[cfg(all(
193    not(feature = "runtime-tokio"),
194    not(feature = "runtime-smol"),
195    not(feature = "runtime-async-std"),
196    not(feature = "runtime-embassy"),
197    feature = "runtime-wasm"
198))]
199pub type WasmTimestamped<T> = InstantTimestamped<T, WasmRuntime>;
200
201#[cfg(feature = "runtime-embassy")]
202pub use fluxion_runtime::impls::embassy::EmbassyRuntime;
203
204#[cfg(feature = "runtime-embassy")]
205pub type EmbassyTimestamped<T> = InstantTimestamped<T, EmbassyRuntime>;
206
207#[cfg(all(feature = "runtime-tokio", not(target_arch = "wasm32")))]
208pub type DefaultRuntime = fluxion_runtime::impls::tokio::TokioRuntime;
209
210#[cfg(all(
211    not(all(feature = "runtime-tokio", not(target_arch = "wasm32"))),
212    feature = "runtime-smol"
213))]
214pub type DefaultRuntime = fluxion_runtime::impls::smol::SmolRuntime;
215
216#[cfg(all(
217    not(all(feature = "runtime-tokio", not(target_arch = "wasm32"))),
218    not(feature = "runtime-smol"),
219    feature = "runtime-async-std"
220))]
221pub type DefaultRuntime = fluxion_runtime::impls::async_std::AsyncStdRuntime;
222
223#[cfg(all(
224    not(all(feature = "runtime-tokio", not(target_arch = "wasm32"))),
225    not(feature = "runtime-smol"),
226    not(feature = "runtime-async-std"),
227    feature = "runtime-embassy"
228))]
229pub type DefaultRuntime = fluxion_runtime::impls::embassy::EmbassyRuntime;
230
231#[cfg(all(
232    not(all(feature = "runtime-tokio", not(target_arch = "wasm32"))),
233    not(feature = "runtime-smol"),
234    not(feature = "runtime-async-std"),
235    not(feature = "runtime-embassy"),
236    feature = "runtime-wasm"
237))]
238pub type DefaultRuntime = fluxion_runtime::impls::wasm::WasmRuntime;