openwhisk_rust/client/
native_client.rs

1use super::common::{whisk_errors, OpenWhisk, WhiskError};
2use crate::api::{HttpMethods, Service};
3use http::StatusCode;
4use reqwest::blocking::Client;
5use serde_json::Value;
6
7/// A Client to make Requests with.
8#[derive(Debug, Default)]
9pub struct NativeClient(Client);
10
11impl OpenWhisk for NativeClient {
12    /// NativeClient - Http Client (Here client is Reqwest Client)
13    type Output = NativeClient;
14    /// Creates New WhiskClient
15    ///
16    /// # Arguments
17    /// * `insecure` - Option of Bool to specify connection type
18    fn new_whisk_client(insecure: Option<bool>) -> Self::Output {
19        match insecure {
20            Some(x) => match x {
21                true => NativeClient(
22                    reqwest::blocking::Client::builder()
23                        .danger_accept_invalid_certs(x)
24                        .timeout(None)
25                        .build()
26                        .unwrap(),
27                ),
28                false => NativeClient(
29                    reqwest::blocking::Client::builder()
30                        .timeout(None)
31                        .build()
32                        .unwrap(),
33                ),
34            },
35            None => todo!(),
36        }
37    }
38}
39
40impl Service for NativeClient {
41    type Output = reqwest::blocking::RequestBuilder;
42
43    ///
44    /// Creates New Request and Returns  `reqwest::blocking::RequestBuilder`
45    ///
46    /// # Arguments
47    /// * `method`   - Option of HTTPMethods
48    /// * `url`      - API Host url
49    /// * `use_auth` - Option of tuple conatining Username and Password
50    /// * `body`     - Option of value which can have parameters necessary for the body of request
51    ///
52    fn new_request(
53        &self,
54        method: Option<HttpMethods>,
55        url: &str,
56        use_auth: Option<(&str, &str)>,
57        body: Option<Value>,
58    ) -> Result<Self::Output, String> {
59        let body = body.unwrap_or_else(|| serde_json::json!({}));
60
61        match use_auth {
62            Some(auth) => {
63                let user = auth.0;
64                let pass = auth.1;
65
66                match method {
67                    Some(http_method) => match http_method {
68                        HttpMethods::GET => Ok(self.0.get(url).basic_auth(user, Some(pass))),
69                        HttpMethods::POST => {
70                            Ok(self.0.post(url).basic_auth(user, Some(pass)).json(&body))
71                        }
72                        HttpMethods::PUT => {
73                            Ok(self.0.put(url).basic_auth(user, Some(pass)).json(&body))
74                        }
75                        HttpMethods::DELETE => {
76                            Ok(self.0.delete(url).basic_auth(user, Some(pass)).json(&body))
77                        }
78                    },
79                    None => Err("Falied to create request".to_string()),
80                }
81            }
82            None => match method {
83                Some(http_method) => match http_method {
84                    HttpMethods::GET => Ok(self.0.get(url)),
85                    HttpMethods::POST => Ok(self.0.post(url).json(&body)),
86                    HttpMethods::PUT => Ok(self.0.put(url).json(&body)),
87                    HttpMethods::DELETE => Ok(self.0.delete(url).json(&body)),
88                },
89                None => Err("Falied to create request".to_string()),
90            },
91        }
92    }
93
94    ///
95    /// To invoke request and get response out of request execution
96    ///
97    /// # Arguments
98    ///
99    /// * `request` - Http request with url,auth and body
100    ///
101    ///
102    ///
103    fn invoke_request(&self, request: Self::Output) -> Result<Value, String> {
104        match request.send() {
105            Ok(response) => match response.status() {
106                StatusCode::OK => Ok(response.json().unwrap()),
107                _ => {
108                    let code = response.status();
109                    let error: WhiskError = response.json().unwrap();
110
111                    Err(whisk_errors(code, error.error))
112                }
113            },
114            Err(error) => Err(format!("{}", error)),
115        }
116    }
117}
118
119impl Clone for NativeClient {
120    fn clone(&self) -> Self {
121        NativeClient(self.0.clone())
122    }
123
124    #[allow(clippy::unnecessary_operation)]
125    fn clone_from(&mut self, _source: &Self) {
126        NativeClient(self.0.clone());
127    }
128}