1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::GithubClient;
use anyhow::{bail, Result};
use async_trait::async_trait;
use jacklog::debug;
use serde::{Deserialize, Serialize};

#[derive(Deserialize, Debug)]
pub struct GetAuthenticatedUserResponse {
    user: User,
}

#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct User {
    pub login: String,
    pub id: u64,
    pub node_id: String,
    #[serde(rename = "type")]
    pub _type: String,
    pub site_admin: bool,
}

#[async_trait]
pub trait Users {
    // TODO: rename this
    async fn get_authenticated_user(&self) -> Result<GetAuthenticatedUserResponse>;
}

#[async_trait]
impl Users for GithubClient {
    async fn get_authenticated_user(&self) -> Result<GetAuthenticatedUserResponse> {
        // Hit the user endpoint.
        let req = self.client().get("https://api.github.com/user");
        debug!("{:?}", &req);

        let res = req.send().await?;
        if !res.status().is_success() {
            bail!("{}", res.status().canonical_reason().unwrap_or(&"unknown"));
        }

        let user = res.json().await?;
        debug!("{:#?}", &user);
        Ok(GetAuthenticatedUserResponse { user })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{client, handle, log};

    #[tokio::test]
    async fn test_whoami() {
        let client = client();
        let res = client.get_authenticated_user().await.unwrap();
        assert_eq!(res.user.login, handle());
    }
}