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
58
59
60
61
62
63
64
65
66
67
68
use crate::{
    types::{
        ApiResponse,
        UserData,
    },
    Error,
};
use std::time::Duration;

/// An R6Stats client
#[derive(Debug, Clone)]
pub struct Client {
    /// The inner http client
    pub client: reqwest::Client,
}

impl Client {
    /// Make a new client.
    pub fn new() -> Self {
        let client = reqwest::Client::builder()
            .connect_timeout(Duration::from_secs(10))
            .build()
            .expect("failed to build client");

        Client { client }
    }

    // TODO: Add non-pc support
    /// Search for a PC user's profile by name.
    pub async fn search(&self, name: &str) -> Result<Vec<UserData>, Error> {
        let url = format!("https://r6stats.com/api/player-search/{name}/pc");
        let text = self.client.get(&url).send().await?.text().await?;
        let response: ApiResponse<Vec<UserData>> = serde_json::from_str(&text)?;

        Ok(response.data)
    }
}

impl Default for Client {
    fn default() -> Self {
        Client::new()
    }
}

#[cfg(test)]
mod test {
    use super::*;

    // 9/1/2023: Online is currently broken, ignore
    #[tokio::test]
    #[ignore]
    async fn it_works() {
        let client = Client::new();
        let user_list = client.search("KingGeorge").await.unwrap();
        assert!(!user_list.is_empty());
        dbg!(&user_list);
    }

    // 9/1/2023: Online is currently broken, ignore
    #[tokio::test]
    #[ignore]
    async fn invalid_search() {
        let client = Client::new();
        let user_list = client.search("ygwdauiwgd").await.unwrap();
        assert!(user_list.is_empty());
        dbg!(&user_list);
    }
}