Implement sipper support through Task::sip 🎉

This commit is contained in:
Héctor Ramón Jiménez 2025-02-09 11:10:54 +01:00
parent 12653114bd
commit c8981d0096
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
4 changed files with 35 additions and 2 deletions

View file

@ -23,5 +23,6 @@ iced_core.workspace = true
iced_futures.workspace = true
iced_futures.features = ["thread-pool"]
thiserror.workspace = true
raw-window-handle.workspace = true
sipper.workspace = true
thiserror.workspace = true

View file

@ -3,7 +3,6 @@ use crate::core::widget;
use crate::futures::futures::channel::mpsc;
use crate::futures::futures::channel::oneshot;
use crate::futures::futures::future::{self, FutureExt};
use crate::futures::futures::never::Never;
use crate::futures::futures::stream::{self, Stream, StreamExt};
use crate::futures::{boxed_stream, BoxStream, MaybeSend};
use crate::Action;
@ -11,6 +10,9 @@ use crate::Action;
use std::future::Future;
use std::sync::Arc;
#[doc(no_inline)]
pub use sipper::{sipper, stream, Never, Sender, Sipper, Straw};
/// A set of concurrent actions to be performed by the iced runtime.
///
/// A [`Task`] _may_ produce a bunch of values of type `T`.
@ -57,6 +59,25 @@ impl<T> Task<T> {
Self::stream(stream.map(f))
}
/// Creates a [`Task`] that runs the given [`Sipper`] to completion, mapping
/// progress with the first closure and the output with the second one.
pub fn sip<S, Output, Progress>(
sipper: S,
on_progress: impl Fn(Progress) -> T + Send + 'static,
on_output: impl FnOnce(Output) -> T + Send + 'static,
) -> Self
where
S: Sipper<Output, Progress> + Send + 'static,
S::Future: Send + 'static,
Output: Send,
Progress: Send,
T: Send + 'static,
{
Self::stream(stream(sipper::sipper(move |sender| async move {
on_output(sipper.map(on_progress).run(sender).await)
})))
}
/// Combines the given tasks and produces a single [`Task`] that will run all of them
/// in parallel.
pub fn batch(tasks: impl IntoIterator<Item = Self>) -> Self