Implement Subscription::with
This commit is contained in:
parent
85ee2fc65a
commit
a6531c840b
2 changed files with 77 additions and 6 deletions
|
|
@ -77,8 +77,6 @@ impl Application for Launcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!(self);
|
|
||||||
|
|
||||||
Command::none()
|
Command::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,11 +86,14 @@ impl Application for Launcher {
|
||||||
match example {
|
match example {
|
||||||
Example::Clock(clock) => clock
|
Example::Clock(clock) => clock
|
||||||
.subscription()
|
.subscription()
|
||||||
.map(move |message| Message::Clock(pane, message)),
|
.with(pane)
|
||||||
|
.map(|(pane, message)| Message::Clock(pane, message)),
|
||||||
|
|
||||||
Example::Stopwatch(stopwatch) => stopwatch
|
Example::Stopwatch(stopwatch) => {
|
||||||
.subscription()
|
stopwatch.subscription().with(pane).map(
|
||||||
.map(move |message| Message::Stopwatch(pane, message)),
|
|(pane, message)| Message::Stopwatch(pane, message),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,34 @@ where
|
||||||
self.recipes
|
self.recipes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a value to the [`Subscription`] context.
|
||||||
|
///
|
||||||
|
/// The value will be part of the identity of a [`Subscription`].
|
||||||
|
///
|
||||||
|
/// This is necessary if you want to use multiple instances of the same
|
||||||
|
/// [`Subscription`] to produce different kinds of messages based on some
|
||||||
|
/// external data.
|
||||||
|
///
|
||||||
|
/// [`Subscription`]: struct.Subscription.html
|
||||||
|
pub fn with<T>(mut self, value: T) -> Subscription<H, E, (T, O)>
|
||||||
|
where
|
||||||
|
H: 'static,
|
||||||
|
E: 'static,
|
||||||
|
O: 'static,
|
||||||
|
T: std::hash::Hash + Clone + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
Subscription {
|
||||||
|
recipes: self
|
||||||
|
.recipes
|
||||||
|
.drain(..)
|
||||||
|
.map(|recipe| {
|
||||||
|
Box::new(With::new(recipe, value.clone()))
|
||||||
|
as Box<dyn Recipe<H, E, Output = (T, O)>>
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Transforms the [`Subscription`] output with the given function.
|
/// Transforms the [`Subscription`] output with the given function.
|
||||||
///
|
///
|
||||||
/// [`Subscription`]: struct.Subscription.html
|
/// [`Subscription`]: struct.Subscription.html
|
||||||
|
|
@ -187,3 +215,45 @@ where
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct With<Hasher, Event, A, B> {
|
||||||
|
recipe: Box<dyn Recipe<Hasher, Event, Output = A>>,
|
||||||
|
value: B,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, E, A, B> With<H, E, A, B> {
|
||||||
|
fn new(recipe: Box<dyn Recipe<H, E, Output = A>>, value: B) -> Self {
|
||||||
|
With { recipe, value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<H, E, A, B> Recipe<H, E> for With<H, E, A, B>
|
||||||
|
where
|
||||||
|
A: 'static,
|
||||||
|
B: 'static + std::hash::Hash + Clone + Send + Sync,
|
||||||
|
H: std::hash::Hasher,
|
||||||
|
{
|
||||||
|
type Output = (B, A);
|
||||||
|
|
||||||
|
fn hash(&self, state: &mut H) {
|
||||||
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
std::any::TypeId::of::<B>().hash(state);
|
||||||
|
self.value.hash(state);
|
||||||
|
self.recipe.hash(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stream(
|
||||||
|
self: Box<Self>,
|
||||||
|
input: BoxStream<'static, E>,
|
||||||
|
) -> futures::stream::BoxStream<'static, Self::Output> {
|
||||||
|
use futures::StreamExt;
|
||||||
|
|
||||||
|
let value = self.value;
|
||||||
|
|
||||||
|
self.recipe
|
||||||
|
.stream(input)
|
||||||
|
.map(move |element| (value.clone(), element))
|
||||||
|
.boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue