diff options
| author | 2020-03-23 20:37:30 +0100 | |
|---|---|---|
| committer | 2020-03-23 20:37:30 +0100 | |
| commit | b92e1f957408e3254e5fe0da389808474de6c4a9 (patch) | |
| tree | cc33a8f1682c0876d9fefc7cadc160c1073ed33b /examples/download_progress/src/download.rs | |
| parent | 30c7db3f25d12461f2dec493f92c3f3282bd264d (diff) | |
| download | iced-b92e1f957408e3254e5fe0da389808474de6c4a9.tar.gz iced-b92e1f957408e3254e5fe0da389808474de6c4a9.tar.bz2 iced-b92e1f957408e3254e5fe0da389808474de6c4a9.zip  | |
Rename `downloader` module to `download`
Diffstat (limited to 'examples/download_progress/src/download.rs')
| -rw-r--r-- | examples/download_progress/src/download.rs | 94 | 
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, +}  | 
