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}