diff options
author | 2020-03-05 02:08:53 +0100 | |
---|---|---|
committer | 2020-03-05 02:08:53 +0100 | |
commit | a6531c840b97b1d30af5153c01fda69d09f43a08 (patch) | |
tree | 3beff9659e8cad42e51098efb3bd1cf35b5405b6 /futures/src | |
parent | 85ee2fc65a955f6020113a20b585bf3432a794a6 (diff) | |
download | iced-a6531c840b97b1d30af5153c01fda69d09f43a08.tar.gz iced-a6531c840b97b1d30af5153c01fda69d09f43a08.tar.bz2 iced-a6531c840b97b1d30af5153c01fda69d09f43a08.zip |
Implement `Subscription::with`
Diffstat (limited to 'futures/src')
-rw-r--r-- | futures/src/subscription.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index b68444cd..8eccb7be 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -72,6 +72,34 @@ where 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. /// /// [`Subscription`]: struct.Subscription.html @@ -187,3 +215,45 @@ where .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() + } +} |