From b92e1f957408e3254e5fe0da389808474de6c4a9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 20:37:30 +0100 Subject: Rename `downloader` module to `download` --- examples/download_progress/src/download.rs | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 examples/download_progress/src/download.rs (limited to 'examples/download_progress/src/download.rs') diff --git a/examples/download_progress/src/download.rs b/examples/download_progress/src/download.rs new file mode 100644 index 00000000..0562f54d --- /dev/null +++ b/examples/download_progress/src/download.rs @@ -0,0 +1,94 @@ +use iced_futures::futures; + +// Just a little utility function +pub fn file(url: T) -> iced::Subscription { + iced::Subscription::from_recipe(Download { + url: url.to_string(), + }) +} + +pub struct Download { + url: String, +} + +// Make sure iced can use our download stream +impl iced_native::subscription::Recipe for Download +where + H: std::hash::Hasher, +{ + type Output = Progress; + + fn hash(&self, state: &mut H) { + use std::hash::Hash; + std::any::TypeId::of::().hash(state); + } + + fn stream( + self: Box, + _input: futures::stream::BoxStream<'static, I>, + ) -> futures::stream::BoxStream<'static, Self::Output> { + Box::pin(futures::stream::unfold( + State::Ready(self.url), + |state| async move { + match state { + State::Ready(url) => { + let response = reqwest::get(&url).await; + + match response { + Ok(response) => Some(( + Progress::Started, + State::Downloading { + total: response.content_length().unwrap(), + downloaded: 0, + response, + }, + )), + Err(_) => None, + } + } + State::Downloading { + mut response, + total, + downloaded, + } => match response.chunk().await { + Ok(Some(chunk)) => { + let downloaded = downloaded + chunk.len() as u64; + + let percentage = + (downloaded as f32 / total as f32) * 100.0; + + Some(( + Progress::Advanced(percentage), + State::Downloading { + response, + total, + downloaded, + }, + )) + } + Ok(None) => Some((Progress::Finished, State::Finished)), + Err(_) => None, + }, + State::Finished => None, + } + }, + )) + } +} + +#[derive(Debug, Clone)] +pub enum Progress { + Started, + Advanced(f32), + Finished, +} + +pub enum State { + Ready(String), + Downloading { + response: reqwest::Response, + total: u64, + downloaded: u64, + }, + Finished, +} -- cgit From 0d719bbdf336a022c073986e1e5a91cf632a270c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 23 Mar 2020 20:43:55 +0100 Subject: Handle errors in `download_progress` example --- examples/download_progress/src/download.rs | 38 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 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 0562f54d..96e1dc28 100644 --- a/examples/download_progress/src/download.rs +++ b/examples/download_progress/src/download.rs @@ -35,15 +35,23 @@ where let response = reqwest::get(&url).await; match response { - Ok(response) => Some(( - Progress::Started, - State::Downloading { - total: response.content_length().unwrap(), - downloaded: 0, - response, - }, - )), - Err(_) => None, + Ok(response) => { + if let Some(total) = response.content_length() { + Some(( + Progress::Started, + State::Downloading { + response, + total, + downloaded: 0, + }, + )) + } else { + Some((Progress::Errored, State::Finished)) + } + } + Err(_) => { + Some((Progress::Errored, State::Finished)) + } } } State::Downloading { @@ -67,9 +75,16 @@ where )) } Ok(None) => Some((Progress::Finished, State::Finished)), - Err(_) => None, + Err(_) => Some((Progress::Errored, State::Finished)), }, - State::Finished => None, + State::Finished => { + // We do not let the stream die, as it would start a + // new download repeatedly if the user is not careful + // in case of errors. + let _: () = iced::futures::future::pending().await; + + None + } } }, )) @@ -81,6 +96,7 @@ pub enum Progress { Started, Advanced(f32), Finished, + Errored, } pub enum State { -- cgit From fd7d9622e333a0a2cd5c2e8e6cc38cc09d7981e4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 24 Mar 2020 14:07:34 +0100 Subject: Fix `Recipe::hash` in `download_progress` example --- examples/download_progress/src/download.rs | 2 ++ 1 file changed, 2 insertions(+) (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 96e1dc28..f46a01f7 100644 --- a/examples/download_progress/src/download.rs +++ b/examples/download_progress/src/download.rs @@ -20,7 +20,9 @@ where fn hash(&self, state: &mut H) { use std::hash::Hash; + std::any::TypeId::of::().hash(state); + self.url.hash(state); } fn stream( -- cgit