diff options
author | 2020-03-23 15:54:23 +0100 | |
---|---|---|
committer | 2020-03-23 17:53:57 +0100 | |
commit | fff333f89ba99f32171641f0e8d78c9cdfe291b4 (patch) | |
tree | 08d267252d154f0fb936f14195cb5acc40340510 /examples/download_progress/src/downloader.rs | |
parent | 092e9fb4cc3edcf2083b4464d24d50c82a1163d2 (diff) | |
download | iced-fff333f89ba99f32171641f0e8d78c9cdfe291b4.tar.gz iced-fff333f89ba99f32171641f0e8d78c9cdfe291b4.tar.bz2 iced-fff333f89ba99f32171641f0e8d78c9cdfe291b4.zip |
Add example for download with progress tracking
Diffstat (limited to 'examples/download_progress/src/downloader.rs')
-rw-r--r-- | examples/download_progress/src/downloader.rs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/examples/download_progress/src/downloader.rs b/examples/download_progress/src/downloader.rs new file mode 100644 index 00000000..62f943fd --- /dev/null +++ b/examples/download_progress/src/downloader.rs @@ -0,0 +1,99 @@ +use iced_futures::futures; + +// Just a little utility function +pub fn file<T: ToString>(url: T) -> iced::Subscription<DownloadMessage> { + iced::Subscription::from_recipe(Downloader { + url: url.to_string(), + }) +} + +pub struct Downloader { + url: String, +} + +// Make sure iced can use our download stream +impl<H, I> iced_native::subscription::Recipe<H, I> for Downloader +where + H: std::hash::Hasher, +{ + type Output = DownloadMessage; + + 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> { + use isahc::prelude::*; + + Box::pin(futures::stream::unfold( + DownloadState::Ready(self.url), + |state| async move { + match state { + DownloadState::Ready(url) => { + let resp = Request::get(&url) + .metrics(true) + .body(()) + .unwrap() + .send_async() + .await + .unwrap(); + let metrics = resp.metrics().unwrap().clone(); + // If you actually want to download: + /*let file = async_std::fs::File::create("download.bin") + .await + .unwrap();*/ + + async_std::task::spawn(async_std::io::copy( + resp.into_body(), + async_std::io::sink(), //file + )); + + Some(( + DownloadMessage::DownloadStarted, + DownloadState::Downloading(metrics), + )) + } + DownloadState::Downloading(metrics) => { + async_std::task::sleep( + std::time::Duration::from_millis(100), + ) + .await; + + let percentage = metrics.download_progress().0 * 100 + / metrics.download_progress().1; + + if percentage == 100 { + Some(( + DownloadMessage::Done, + DownloadState::Finished, + )) + } else { + Some(( + DownloadMessage::Downloading(percentage), + DownloadState::Downloading(metrics), + )) + } + } + DownloadState::Finished => None, + } + }, + )) + } +} + +#[derive(Debug)] +pub enum DownloadMessage { + DownloadStarted, + Downloading(u64), + Done, +} + +pub enum DownloadState { + Ready(String), + Downloading(isahc::Metrics), + Finished, +} |