From c8981d00963dac0dc03e6351255ba8823519162c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 9 Feb 2025 11:10:54 +0100 Subject: Implement `sipper` support through `Task::sip` :tada: --- runtime/src/task.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'runtime/src/task.rs') diff --git a/runtime/src/task.rs b/runtime/src/task.rs index 22cfb63e..fb46ca45 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -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 Task { 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( + sipper: S, + on_progress: impl Fn(Progress) -> T + Send + 'static, + on_output: impl FnOnce(Output) -> T + Send + 'static, + ) -> Self + where + S: Sipper + 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) -> Self -- cgit From 7ba2e3913395b212c7789569e1d683e7766cc348 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 9 Feb 2025 21:05:42 +0100 Subject: Update `sipper` and relax `Send` requirements --- runtime/src/task.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'runtime/src/task.rs') diff --git a/runtime/src/task.rs b/runtime/src/task.rs index fb46ca45..989f0ed5 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -63,18 +63,15 @@ impl Task { /// progress with the first closure and the output with the second one. pub fn sip( sipper: S, - on_progress: impl Fn(Progress) -> T + Send + 'static, - on_output: impl FnOnce(Output) -> T + Send + 'static, + on_progress: impl Fn(Progress) -> T + MaybeSend + 'static, + on_output: impl FnOnce(Output) -> T + MaybeSend + 'static, ) -> Self where - S: Sipper + Send + 'static, - S::Future: Send + 'static, - Output: Send, - Progress: Send, - T: Send + 'static, + S: Sipper + MaybeSend + 'static, + T: MaybeSend + 'static, { Self::stream(stream(sipper::sipper(move |sender| async move { - on_output(sipper.map(on_progress).run(sender).await) + on_output(sipper.with(on_progress).run(sender).await) }))) } -- cgit From 6154395be0668af42ac597c9db35e5e198c264c9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 10 Feb 2025 17:47:18 +0100 Subject: Use `sipper::Core` in `Task::sip` --- runtime/src/task.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'runtime/src/task.rs') diff --git a/runtime/src/task.rs b/runtime/src/task.rs index 989f0ed5..bfc36d75 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -61,13 +61,13 @@ impl Task { /// 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( + pub fn sip( sipper: S, - on_progress: impl Fn(Progress) -> T + MaybeSend + 'static, - on_output: impl FnOnce(Output) -> T + MaybeSend + 'static, + on_progress: impl Fn(S::Progress) -> T + MaybeSend + 'static, + on_output: impl FnOnce(::Output) -> T + MaybeSend + 'static, ) -> Self where - S: Sipper + MaybeSend + 'static, + S: sipper::Core + MaybeSend + 'static, T: MaybeSend + 'static, { Self::stream(stream(sipper::sipper(move |sender| async move { -- cgit From 9f21eae1528fa414adbfb987ce4c851fa58326fe Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 11 Feb 2025 02:34:10 +0100 Subject: Introduce `Task::map_with` --- runtime/src/task.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'runtime/src/task.rs') diff --git a/runtime/src/task.rs b/runtime/src/task.rs index bfc36d75..1a1ef699 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -98,6 +98,50 @@ impl Task { self.then(move |output| Task::done(f(output))) } + /// Combines a prefix value with the result of the [`Task`] using + /// the provided closure. + /// + /// Sometimes you will want to identify the source or target + /// of some [`Task`] in your UI. This can be achieved through + /// normal means by using [`map`]: + /// + /// ```rust + /// # use iced_runtime::Task; + /// # let task = Task::none(); + /// # enum Message { TaskCompleted(u32, ()) } + /// let id = 123; + /// + /// # let _ = { + /// task.map(move |result| Message::TaskCompleted(id, result)) + /// # }; + /// ``` + /// + /// Quite a mouthful. [`map_with`] lets you write: + /// + /// ```rust + /// # use iced_runtime::Task; + /// # let task = Task::none(); + /// # enum Message { TaskCompleted(u32, ()) } + /// # let id = 123; + /// # let _ = { + /// task.map_with(id, Message::TaskCompleted) + /// # }; + /// ``` + /// + /// Much nicer! + pub fn map_with( + self, + prefix: P, + mut f: impl FnMut(P, T) -> O + MaybeSend + 'static, + ) -> Task + where + T: MaybeSend + 'static, + P: MaybeSend + Clone + 'static, + O: MaybeSend + 'static, + { + self.map(move |result| f(prefix.clone(), result)) + } + /// Performs a new [`Task`] for every output of the current [`Task`] using the /// given closure. /// -- cgit From 0c528be2ea74f9aae1d4ac80b282ba9c16674649 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 11 Feb 2025 03:39:42 +0100 Subject: Introduce `with` helper and use `sipper` in `gallery` example --- runtime/src/task.rs | 46 +--------------------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) (limited to 'runtime/src/task.rs') diff --git a/runtime/src/task.rs b/runtime/src/task.rs index 1a1ef699..022483f7 100644 --- a/runtime/src/task.rs +++ b/runtime/src/task.rs @@ -63,7 +63,7 @@ impl Task { /// progress with the first closure and the output with the second one. pub fn sip( sipper: S, - on_progress: impl Fn(S::Progress) -> T + MaybeSend + 'static, + on_progress: impl FnMut(S::Progress) -> T + MaybeSend + 'static, on_output: impl FnOnce(::Output) -> T + MaybeSend + 'static, ) -> Self where @@ -98,50 +98,6 @@ impl Task { self.then(move |output| Task::done(f(output))) } - /// Combines a prefix value with the result of the [`Task`] using - /// the provided closure. - /// - /// Sometimes you will want to identify the source or target - /// of some [`Task`] in your UI. This can be achieved through - /// normal means by using [`map`]: - /// - /// ```rust - /// # use iced_runtime::Task; - /// # let task = Task::none(); - /// # enum Message { TaskCompleted(u32, ()) } - /// let id = 123; - /// - /// # let _ = { - /// task.map(move |result| Message::TaskCompleted(id, result)) - /// # }; - /// ``` - /// - /// Quite a mouthful. [`map_with`] lets you write: - /// - /// ```rust - /// # use iced_runtime::Task; - /// # let task = Task::none(); - /// # enum Message { TaskCompleted(u32, ()) } - /// # let id = 123; - /// # let _ = { - /// task.map_with(id, Message::TaskCompleted) - /// # }; - /// ``` - /// - /// Much nicer! - pub fn map_with( - self, - prefix: P, - mut f: impl FnMut(P, T) -> O + MaybeSend + 'static, - ) -> Task - where - T: MaybeSend + 'static, - P: MaybeSend + Clone + 'static, - O: MaybeSend + 'static, - { - self.map(move |result| f(prefix.clone(), result)) - } - /// Performs a new [`Task`] for every output of the current [`Task`] using the /// given closure. /// -- cgit