summaryrefslogtreecommitdiffstats
path: root/examples/download_progress/src/download.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/download_progress/src/download.rs')
-rw-r--r--examples/download_progress/src/download.rs94
1 files changed, 94 insertions, 0 deletions
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<T: ToString>(url: T) -> iced::Subscription<Progress> {
+ iced::Subscription::from_recipe(Download {
+ url: url.to_string(),
+ })
+}
+
+pub struct Download {
+ url: String,
+}
+
+// Make sure iced can use our download stream
+impl<H, I> iced_native::subscription::Recipe<H, I> for Download
+where
+ H: std::hash::Hasher,
+{
+ type Output = Progress;
+
+ fn hash(&self, state: &mut H) {
+ use std::hash::Hash;
+ std::any::TypeId::of::<Self>().hash(state);
+ }
+
+ fn stream(
+ self: Box<Self>,
+ _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,
+}