summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-15 11:45:19 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-01-15 11:45:19 +0700
commit75348c5b8cbe7f997e4c704021fdce8fd9bd862c (patch)
treec4fe591f9a1e78b4c0f58965070506e6a4beb1cf /examples
parent35e4f307595cbb67687afcbc8d96ad97109210b5 (diff)
downloadiced-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.rs153
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)]