diff options
author | 2022-01-15 11:45:19 +0700 | |
---|---|---|
committer | 2022-01-15 11:45:19 +0700 | |
commit | 75348c5b8cbe7f997e4c704021fdce8fd9bd862c (patch) | |
tree | c4fe591f9a1e78b4c0f58965070506e6a4beb1cf /examples | |
parent | 35e4f307595cbb67687afcbc8d96ad97109210b5 (diff) | |
download | iced-75348c5b8cbe7f997e4c704021fdce8fd9bd862c.tar.gz iced-75348c5b8cbe7f997e4c704021fdce8fd9bd862c.tar.bz2 iced-75348c5b8cbe7f997e4c704021fdce8fd9bd862c.zip |
Use `subscription::run` for `download_progress` example
Diffstat (limited to 'examples')
-rw-r--r-- | examples/download_progress/src/download.rs | 153 |
1 files changed, 69 insertions, 84 deletions
diff --git a/examples/download_progress/src/download.rs b/examples/download_progress/src/download.rs index 08805f13..06d5d3fd 100644 --- a/examples/download_progress/src/download.rs +++ b/examples/download_progress/src/download.rs @@ -1,112 +1,97 @@ +use futures::Stream; use iced_futures::futures; -use std::hash::{Hash, Hasher}; +use iced_native::subscription; + +use std::hash::Hash; // Just a little utility function pub fn file<I: 'static + Hash + Copy + Send, T: ToString>( id: I, url: T, ) -> iced::Subscription<(I, Progress)> { - iced::Subscription::from_recipe(Download { - id, - url: url.to_string(), - }) + subscription::run( + Download { + id, + url: url.to_string(), + }, + download, + ) } +#[derive(Debug, Hash, Clone)] pub struct Download<I> { id: I, url: String, } -// Make sure iced can use our download stream -impl<H, I, T> iced_native::subscription::Recipe<H, I> for Download<T> -where - T: 'static + Hash + Copy + Send, - H: Hasher, -{ - type Output = (T, Progress); - - fn hash(&self, state: &mut H) { - struct Marker; - std::any::TypeId::of::<Marker>().hash(state); - - self.id.hash(state); - } - - fn stream( - self: Box<Self>, - _input: futures::stream::BoxStream<'static, I>, - ) -> futures::stream::BoxStream<'static, Self::Output> { - let id = self.id; +fn download<I: Copy>( + download: Download<I>, +) -> impl Stream<Item = (I, Progress)> { + let id = download.id; - Box::pin(futures::stream::unfold( - State::Ready(self.url), - move |state| async move { - match state { - State::Ready(url) => { - let response = reqwest::get(&url).await; + futures::stream::unfold( + State::Ready(download.url), + move |state| async move { + match state { + State::Ready(url) => { + let response = reqwest::get(&url).await; - match response { - Ok(response) => { - if let Some(total) = response.content_length() { - Some(( - (id, Progress::Started), - State::Downloading { - response, - total, - downloaded: 0, - }, - )) - } else { - Some(( - (id, Progress::Errored), - State::Finished, - )) - } - } - Err(_) => { + match response { + Ok(response) => { + if let Some(total) = response.content_length() { + Some(( + (id, Progress::Started), + State::Downloading { + response, + total, + downloaded: 0, + }, + )) + } else { Some(((id, Progress::Errored), State::Finished)) } } - } - 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(( - (id, Progress::Advanced(percentage)), - State::Downloading { - response, - total, - downloaded, - }, - )) - } - 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 - // new download repeatedly if the user is not careful - // in case of errors. - let _: () = iced::futures::future::pending().await; + } + } + State::Downloading { + mut response, + total, + downloaded, + } => match response.chunk().await { + Ok(Some(chunk)) => { + let downloaded = downloaded + chunk.len() as u64; - None + let percentage = + (downloaded as f32 / total as f32) * 100.0; + + Some(( + (id, Progress::Advanced(percentage)), + State::Downloading { + response, + total, + downloaded, + }, + )) + } + 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 + // new download repeatedly if the user is not careful + // in case of errors. + let _: () = iced::futures::future::pending().await; + + None } - }, - )) - } + } + }, + ) } #[derive(Debug, Clone)] |