chore: extract Emitter and Signal to their own crate

This commit is contained in:
2025-04-21 16:43:17 -04:00
parent f422888d37
commit a97cf73061
6 changed files with 403 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
use ext_trait::extension;
use tokio::{select, task::JoinHandle};
use super::emitter::{Capacity, Emitter, NextError};
#[extension(pub trait EmitterExt)]
impl<T> Emitter<T> {
fn map<M, F>(self, mut func: F, capacity: Capacity) -> (Emitter<M>, JoinHandle<()>)
where
T: Send + 'static + Clone,
M: Send + 'static + Clone,
F: Send + 'static + FnMut(T) -> M,
{
Emitter::new(
|mut publisher_stream| async move {
while let Some(publisher) = publisher_stream.wait().await {
let Ok(mut subscription) = self.listen() else {
return;
};
loop {
select! {
biased;
_ = publisher.all_unsubscribed() => {
break;
}
event_res = subscription.next() => {
match event_res {
Ok(event) => publisher.publish(func(event)),
Err(NextError::Lagged { .. }) => {},
Err(NextError::ProducerExited(_)) => return,
}
}
}
}
}
},
capacity,
)
}
fn filter<F>(self, mut func: F, capacity: Capacity) -> (Emitter<T>, JoinHandle<()>)
where
T: Send + 'static + Clone,
F: Send + 'static + FnMut(&T) -> bool,
{
Emitter::new(
|mut publisher_stream| async move {
while let Some(publisher) = publisher_stream.wait().await {
let Ok(mut subscription) = self.listen() else {
return;
};
loop {
select! {
biased;
_ = publisher.all_unsubscribed() => {
break;
}
event_res = subscription.next() => {
match event_res {
Ok(event) => if func(&event) {
publisher.publish(event)
},
Err(NextError::Lagged { .. }) => {},
Err(NextError::ProducerExited(_)) => return,
}
}
}
}
}
},
capacity,
)
}
fn filter_mut<F>(self, mut func: F, capacity: Capacity) -> (Emitter<T>, JoinHandle<()>)
where
T: Send + 'static + Clone,
F: Send + 'static + FnMut(&mut T) -> bool,
{
Emitter::new(
|mut publisher_stream| async move {
while let Some(publisher) = publisher_stream.wait().await {
let Ok(mut subscription) = self.listen() else {
return;
};
loop {
select! {
biased;
_ = publisher.all_unsubscribed() => {
break;
}
event_res = subscription.next() => {
match event_res {
Ok(mut event) => if func(&mut event) {
publisher.publish(event)
},
Err(NextError::Lagged { .. }) => {},
Err(NextError::ProducerExited(_)) => return,
}
}
}
}
}
},
capacity,
)
}
fn filter_map<M, F>(self, mut func: F, capacity: Capacity) -> (Emitter<M>, JoinHandle<()>)
where
T: Send + 'static + Clone,
M: Send + 'static + Clone,
F: Send + 'static + FnMut(T) -> Option<M>,
{
Emitter::new(
|mut publisher_stream| async move {
while let Some(publisher) = publisher_stream.wait().await {
let Ok(mut subscription) = self.listen() else {
return;
};
loop {
select! {
biased;
_ = publisher.all_unsubscribed() => {
break;
}
event_res = subscription.next() => {
match event_res {
Ok(event) => if let Some(mapped) = func(event) {
publisher.publish(mapped)
},
Err(NextError::Lagged { .. }) => {},
Err(NextError::ProducerExited(_)) => return,
}
}
}
}
}
},
capacity,
)
}
}