fetchy/
fetch.rs

1use super::*;
2
3/// A [`Notify`] for fetching data from a URL.
4#[derive(Debug)]
5pub struct Fetch(inner::Fetch);
6
7impl Fetch {
8    /// Create a new [`Notifier`] for fetching data from a URL.
9    // FIXME: Use payload
10    pub(crate) fn new(
11        url: &str,
12        method: Method,
13        headers: Vec<Header<'_>>,
14        body: Vec<u8>,
15    ) -> Self {
16        Self(inner::Fetch::new(url, method, headers, body))
17    }
18
19    /// Get a builder for configuring the fetch request.
20    pub fn builder(url: &str) -> FetchBuilder<'_> {
21        FetchBuilder::new(url)
22    }
23
24    /// Fetch the entire contents all at once.
25    pub async fn all(self) -> Result<Vec<u8>> {
26        struct All(Fetch, Vec<u8>);
27
28        fn fill(
29            all: &mut All,
30            data: Result<Option<Vec<u8>>>,
31        ) -> Poll<Result<Vec<u8>>> {
32            match data {
33                Ok(Some(buf)) => {
34                    all.1.extend(&buf);
35                    Pending
36                }
37                Ok(None) => {
38                    let mut buf = Vec::new();
39                    core::mem::swap(&mut buf, &mut all.1);
40                    Ready(Ok(buf))
41                }
42                Err(e) => Ready(Err(e)),
43            }
44        }
45
46        Loop::new(&mut All(self, Vec::new()))
47            .on(|s| &mut s.0, fill)
48            .await
49    }
50}
51
52impl Notify for Fetch {
53    type Event = Result<Option<Vec<u8>>>;
54
55    fn poll_next(
56        mut self: Pin<&mut Self>,
57        task: &mut Task<'_>,
58    ) -> Poll<Self::Event> {
59        Pin::new(&mut self.0).poll_next(task)
60    }
61}