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}