cloudflare/framework/
mod.rs

1/*!
2This module controls how requests are sent to Cloudflare's API, and how responses are parsed from it.
3 */
4pub mod apiclient;
5pub mod auth;
6pub mod endpoint;
7pub mod mock;
8pub mod response;
9
10use crate::framework::{
11    apiclient::ApiClient, auth::AuthClient, endpoint::Method, response::map_api_response,
12};
13use serde::Serialize;
14
15#[derive(Serialize, Clone, Debug)]
16pub enum OrderDirection {
17    #[serde(rename = "asc")]
18    Ascending,
19    #[serde(rename = "desc")]
20    Descending,
21}
22
23#[derive(Serialize, Clone, Debug)]
24#[serde(rename_all = "lowercase")]
25pub enum SearchMatch {
26    All,
27    Any,
28}
29
30#[derive(Debug)]
31pub enum Environment {
32    Production,
33}
34
35impl<'a> From<&'a Environment> for url::Url {
36    fn from(environment: &Environment) -> Self {
37        match environment {
38            Environment::Production => {
39                url::Url::parse("https://api.cloudflare.com/client/v4/").unwrap()
40            }
41        }
42    }
43}
44
45pub struct HttpApiClient {
46    environment: Environment,
47    credentials: auth::Credentials,
48    http_client: reqwest::Client,
49}
50
51impl HttpApiClient {
52    pub fn new(credentials: auth::Credentials) -> HttpApiClient {
53        HttpApiClient {
54            environment: Environment::Production,
55            credentials,
56            http_client: reqwest::Client::new(),
57        }
58    }
59}
60
61// TODO: This should probably just implement request for the Reqwest client itself :)
62// TODO: It should also probably be called `ReqwestApiClient` rather than `HttpApiClient`.
63impl<'a> ApiClient for HttpApiClient {
64    fn request<ResultType, QueryType, BodyType>(
65        &self,
66        endpoint: &dyn endpoint::Endpoint<ResultType, QueryType, BodyType>,
67    ) -> response::ApiResponse<ResultType>
68    where
69        ResultType: response::ApiResult,
70        QueryType: Serialize,
71        BodyType: Serialize,
72    {
73        fn match_reqwest_method(method: Method) -> reqwest::Method {
74            match method {
75                Method::Get => reqwest::Method::GET,
76                Method::Post => reqwest::Method::POST,
77                Method::Delete => reqwest::Method::DELETE,
78                Method::Put => reqwest::Method::PUT,
79                Method::Patch => reqwest::Method::PATCH,
80            }
81        }
82
83        // Build the request
84        let mut request = self
85            .http_client
86            .request(
87                match_reqwest_method(endpoint.method()),
88                endpoint.url(&self.environment),
89            )
90            .query(&endpoint.query());
91
92        if let Some(body) = endpoint.body() {
93            request = request.body(serde_json::to_string(&body).unwrap());
94            request = request.header(reqwest::header::CONTENT_TYPE, endpoint.content_type());
95        }
96
97        request = request.auth(&self.credentials);
98
99        let response = request.send()?;
100
101        map_api_response(response)
102    }
103}