M src/lib.rs => src/lib.rs +1 -1
@@ 34,7 34,7 @@ pub mod prelude {
executor::Executor,
sync_actor,
traits::{Actor, Event, EventConsumer, EventProducer},
- types::CompletionToken,
+ types::{CompletionToken, Trigger, Waiter},
util::{AsyncActor, AsyncActorError, SyncActor, SyncActorError, WrappedEvent},
wrapped_event,
};
M src/types.rs => src/types.rs +4 -0
@@ 16,6 16,10 @@ use once_cell::sync::Lazy;
use super::traits::{Event, EventConsumer};
+mod waiter;
+
+pub use waiter::{Trigger, Waiter};
+
/// Utility type for generalized errors
pub enum Either<A, B> {
/// The happy path or preferred option
A src/types/waiter.rs => src/types/waiter.rs +42 -0
@@ 0,0 1,42 @@
+//! Utility type for waiting on an event to happen, possibly across a sync/async boundary.
+
+use flume::{Receiver, Sender};
+
+/// Utility type for waiting on an event to happen, possibly across a sync/async boundary.
+pub struct Waiter {
+ /// Internal channel
+ recv: Receiver<()>,
+}
+
+/// Utility type for signaling an event has happend, possibly across a sync/async boundary.
+pub struct Trigger {
+ /// Internal channel
+ send: Sender<()>,
+}
+
+impl Waiter {
+ /// Create a new `Waiter`/`Trigger` pair
+ pub fn new() -> (Waiter, Trigger) {
+ let (send, recv) = flume::bounded(1);
+ (Waiter { recv }, Trigger { send })
+ }
+
+ /// Asynchronously wait for the event, returning `true` if the event happened, or `false` if the
+ /// `Trigger` was dropped before completion
+ pub async fn wait(self) -> bool {
+ self.recv.recv_async().await.is_ok()
+ }
+
+ /// Synchronously wait for the event, returning `true` if the event happened, or `false` if the
+ /// `Trigger` was dropped before completion
+ pub fn wait_sync(self) -> bool {
+ self.recv.recv().is_ok()
+ }
+}
+
+impl Trigger {
+ /// Consume the trigger and signal the waiter
+ pub fn trigger(self) {
+ let _ = self.send.send(());
+ }
+}