From 9f5c2eb0c43daa61b19769322cf3692b29e0ac0f Mon Sep 17 00:00:00 2001 From: Folyd Date: Sat, 13 Feb 2021 05:00:52 +0800 Subject: Improve download_progress example (#283) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add advanced download example * Rename to task fields and variables * Cargo fmt advanced_download/src/download.rs * Add progress bar for advanced download example * Merge two download examples to single one * Apply great review suggestions * Change to url::Url instead of plain String * Simplify `download_progress` example * Update `README` of `download_progress` example Co-authored-by: Héctor Ramón Jiménez --- examples/download_progress/src/download.rs | 46 ++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'examples/download_progress/src/download.rs') diff --git a/examples/download_progress/src/download.rs b/examples/download_progress/src/download.rs index f46a01f7..08805f13 100644 --- a/examples/download_progress/src/download.rs +++ b/examples/download_progress/src/download.rs @@ -1,37 +1,46 @@ use iced_futures::futures; +use std::hash::{Hash, Hasher}; // Just a little utility function -pub fn file(url: T) -> iced::Subscription { +pub fn file( + id: I, + url: T, +) -> iced::Subscription<(I, Progress)> { iced::Subscription::from_recipe(Download { + id, url: url.to_string(), }) } -pub struct Download { +pub struct Download { + id: I, url: String, } // Make sure iced can use our download stream -impl iced_native::subscription::Recipe for Download +impl iced_native::subscription::Recipe for Download where - H: std::hash::Hasher, + T: 'static + Hash + Copy + Send, + H: Hasher, { - type Output = Progress; + type Output = (T, Progress); fn hash(&self, state: &mut H) { - use std::hash::Hash; + struct Marker; + std::any::TypeId::of::().hash(state); - std::any::TypeId::of::().hash(state); - self.url.hash(state); + self.id.hash(state); } fn stream( self: Box, _input: futures::stream::BoxStream<'static, I>, ) -> futures::stream::BoxStream<'static, Self::Output> { + let id = self.id; + Box::pin(futures::stream::unfold( State::Ready(self.url), - |state| async move { + move |state| async move { match state { State::Ready(url) => { let response = reqwest::get(&url).await; @@ -40,7 +49,7 @@ where Ok(response) => { if let Some(total) = response.content_length() { Some(( - Progress::Started, + (id, Progress::Started), State::Downloading { response, total, @@ -48,11 +57,14 @@ where }, )) } else { - Some((Progress::Errored, State::Finished)) + Some(( + (id, Progress::Errored), + State::Finished, + )) } } Err(_) => { - Some((Progress::Errored, State::Finished)) + Some(((id, Progress::Errored), State::Finished)) } } } @@ -68,7 +80,7 @@ where (downloaded as f32 / total as f32) * 100.0; Some(( - Progress::Advanced(percentage), + (id, Progress::Advanced(percentage)), State::Downloading { response, total, @@ -76,8 +88,12 @@ where }, )) } - Ok(None) => Some((Progress::Finished, State::Finished)), - Err(_) => Some((Progress::Errored, State::Finished)), + Ok(None) => { + Some(((id, Progress::Finished), State::Finished)) + } + Err(_) => { + Some(((id, Progress::Errored), State::Finished)) + } }, State::Finished => { // We do not let the stream die, as it would start a -- cgit