Skip to main content

square_rs/
client.rs

1/*!
2The [SquareClient](crate::client::SquareClient) allows the user of the crate
3to use the [Square API](https://developer.squareup.com) in an idiomatic way.
4
5# Example: Creating a client
6In order to create a client you will need your account access token that can be found
7in the [Developer Apps](https://developer.squareup.com/apps) page for the specific
8application you are wanting to use.
9
10```rust
11use square_rs::client::SquareClient;
12let client = SquareClient::new(ACCESS_TOKEN);
13```
14After creating a client you will be able to use all of the clients methods.
15
16*/
17use crate::endpoint::SquareEndpoint;
18use crate::error::SquareError;
19use crate::response::SquareResponse;
20
21use reqwest::{header, Client};
22use serde::Serialize;
23use std::default::Default;
24
25#[derive(Copy, Clone)]
26pub enum ClientMode {
27    Production,
28    Sandboxed,
29}
30
31/// The default mode we start a client in is Sandboxed
32impl Default for ClientMode {
33    fn default() -> Self {
34        Self::Sandboxed
35    }
36}
37
38/// The SquareClient contains many useful methods allowing for convenient
39/// use of the [Square API](https://developer.squareup.com).
40#[derive(Clone)]
41pub struct SquareClient {
42    access_token: String,
43    pub(crate) client_mode: ClientMode,
44}
45
46impl SquareClient {
47    /// Create a new [SquareClient](SquareClient)
48    ///
49    /// # Arguments
50    /// * `access_token` - The access token for the Square App you
51    /// want to use the client with is required.
52    ///
53    /// # Example: Create a new client
54    /// ```
55    /// let client = SquareClient::new(ACCESS_TOKEN);
56    /// ```
57    pub fn new(access_token: &str) -> Self {
58        Self {
59            access_token: access_token.to_string(),
60            client_mode: Default::default(),
61        }
62    }
63
64    /// Set the client to Production Mode
65    ///
66    /// # Arguments
67    /// This method takes no arguments, as by default the client will use SandBox Mode.
68    ///
69    /// # Example
70    /// ```
71    /// let client = SquareClient::new(ACCESS_TOKEN).production();
72    /// ```
73    pub fn production(self) -> Self {
74        Self {
75            access_token: self.access_token,
76            client_mode: ClientMode::Production,
77        }
78    }
79
80    /// Sends a request to a given [SquareEndpoint](crate::endpoint::SquareEndpoint)
81    /// # Arguments
82    /// * `endpoint` - The [SquareEndpoint](crate::endpoint::SquareEndpoint) to send the request to
83    /// * `body` - The json that will be included in the request.
84    /// All types that meet the conditions to be deserialized to JSON are accepted.
85    ///
86    /// # Example:
87    /// ```
88    /// self.request(SquareEndpoint::Payments, &payment).await
89    /// ```
90    pub async fn request<T>(
91        &self,
92        endpoint: SquareEndpoint,
93        json: &T,
94    ) -> Result<SquareResponse, SquareError>
95    where
96        T: Serialize + ?Sized,
97    {
98        let url = &self.endpoint(endpoint);
99        let authorization_header = format!("Bearer {}", &self.access_token);
100
101        // Add the headers to the request
102        let mut headers = header::HeaderMap::new();
103        headers.insert(
104            header::AUTHORIZATION,
105            header::HeaderValue::from_str(&authorization_header)?,
106        );
107
108        // Create a client with the appropiate headers
109        let client = Client::builder().default_headers(headers).build()?;
110
111        // Send the request to the Square API, and get the response
112        let response = client.post(url).json(json).send().await?.text().await?;
113
114        // Deserialize the response into a SquareResponse
115        Ok(serde_json::from_str(&response)?)
116    }
117}