xkcd/
lib.rs

1use reqwest::Url;
2
3/// Library Error type
4///
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7    /// Rewqwest HTTP Error
8    ///
9    #[error("{0}")]
10    Reqwest(#[from] reqwest::Error),
11
12    /// Invalid HTTP StatusCode
13    ///
14    #[error("{0}")]
15    InvalidStatus(reqwest::StatusCode),
16}
17
18/// An XKCD client
19///
20#[derive(Debug, Clone)]
21pub struct Client {
22    client: reqwest::Client,
23}
24
25impl Client {
26    /// Make a new [`Client`].
27    ///
28    pub fn new() -> Self {
29        Client {
30            client: reqwest::Client::new(),
31        }
32    }
33
34    /// Get a random xkcd comic url.
35    ///
36    pub async fn get_random(&self) -> Result<Url, Error> {
37        let res = self
38            .client
39            .get("https://c.xkcd.com/random/comic/")
40            .send()
41            .await?;
42        let status = res.status();
43        if !status.is_success() {
44            return Err(Error::InvalidStatus(status));
45        }
46        let ret = res.url().clone();
47        let _body = res.text().await?;
48
49        Ok(ret)
50    }
51}
52
53impl Default for Client {
54    fn default() -> Self {
55        Self::new()
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[tokio::test]
64    async fn it_works() {
65        let client = Client::new();
66        let result = client.get_random().await.expect("failed to get xkcd comic");
67        dbg!(result);
68    }
69}