Skip to main content

brawl_rs/client/
mod.rs

1//! HTTP client for communicating with the Brawl Stars API.
2//!
3//! This module provides the main [`BrawlClient`] type used to make authenticated requests
4//! to the Brawl Stars API endpoints.
5
6pub mod endpoints;
7
8use crate::client::endpoints::{Endpoint, BASE_URL};
9use crate::errors::{ApiError, BrawlError};
10use reqwest::Client;
11
12/// Main client for interacting with the Brawl Stars API.
13///
14/// The [`BrawlClient`] handles all HTTP communication with the Brawl Stars API,
15/// including authentication, error handling, and JSON deserialization.
16///
17/// # Examples
18///
19/// ```no_run
20/// use brawl_rs::prelude::*;
21///
22/// let client = BrawlClient::new("your_api_token_here");
23/// ```
24///
25pub struct BrawlClient {
26    pub(crate) http: Client,
27    pub(crate) api_key: String,
28}
29
30impl BrawlClient {
31    /// Creates a new [`BrawlClient`] with the provided API key.
32    ///
33    /// The API key can be obtained from the [Brawl Stars Developer Portal](https://developer.brawlstars.com/).
34    ///
35    /// # Arguments
36    ///
37    /// * `api_key` - Your Brawl Stars API token for authentication
38    ///
39    /// # Examples
40    ///
41    /// ```no_run
42    /// use brawl_rs::prelude::*;
43    ///
44    /// let client = BrawlClient::new("eyJ0eXAiOiJKV1QiLCJhbGci...");
45    /// ```
46    pub fn new(api_key: impl Into<String>) -> Self {
47        let client = Client::new();
48        Self {
49            http: client,
50            api_key: api_key.into(),
51        }
52    }
53
54    /// Fetches data from a Brawl Stars API endpoint and deserializes it.
55    ///
56    /// # Errors
57    ///
58    /// Returns [`BrawlError`] if:
59    /// - Network communication fails
60    /// - The API returns an error status
61    /// - JSON deserialization fails
62    ///
63    pub(crate) async fn fetch<T>(&self, endpoint: Endpoint) -> Result<T, BrawlError>
64    where
65        T: serde::de::DeserializeOwned,
66    {
67        let url = format!("{}{}", BASE_URL, endpoint);
68
69        let response = self
70            .http
71            .get(url)
72            .bearer_auth(&self.api_key)
73            .header(
74                "User-Agent",
75                format!("{}/{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")),
76            )
77            .send()
78            .await
79            .map_err(BrawlError::Network)?;
80
81        let status = response.status();
82
83        if status.is_success() {
84            response
85                .json::<T>()
86                .await
87                .map_err(BrawlError::Serialization)
88        } else {
89            let err_body = response
90                .json::<ApiError>()
91                .await
92                .map_err(BrawlError::Serialization)?;
93
94            Err(BrawlError::Api(err_body))
95        }
96    }
97}