lib_remotebuild_rs/
request.rs1use crate::config::RequestConfig;
2use crate::jobs;
3use crate::request_error::Error;
4
5use serde::de::DeserializeOwned;
6use serde::Serialize;
7
8use std::collections::HashMap;
9
10const HEADER_RESPONSE_STATUS: &str = "x-response-status";
11const HEADER_RESPONSE_MESSAGE: &str = "x-response-message";
12const STATUS_SUCCESS: u8 = 1;
13const STATUS_ERROR: u8 = 0;
14
15#[derive(Default)]
16pub struct Request<T>
17where
18 T: Serialize,
19{
20 config: RequestConfig,
21 endpoint: String,
22 method: reqwest::Method,
23 auth: Option<Authorization>,
24 payload: Option<T>,
25}
26
27#[derive(Debug)]
28pub enum AuthorizationType {
29 Bearer,
30 Basic,
31}
32
33impl std::fmt::Display for AuthorizationType {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 write!(f, "{:?}", self)
36 }
37}
38
39pub struct Authorization {
40 auth_type: AuthorizationType,
41 payload: String,
42}
43
44impl Authorization {
45 pub fn new(auth_type: AuthorizationType, payload: String) -> Self {
46 Authorization { auth_type, payload }
47 }
48}
49
50impl<T> Request<T>
51where
52 T: Serialize + Default,
53{
54 pub fn new(config: RequestConfig, endpoint: &str, p: T) -> Self {
57 Request {
58 config,
60 endpoint: endpoint.to_owned(),
61 payload: Some(p),
62 ..Request::default()
63 }
64 }
65
66 pub fn with_auth(&mut self, auth: Authorization) {
68 self.auth = Some(auth);
69 }
70
71 pub fn with_method(&mut self, method: reqwest::Method) {
73 self.method = method;
74 }
75
76 async fn prepare_response(self) -> Result<(reqwest::Response, String, u8), Error> {
78 let mut req_builder = reqwest::Client::new().request(
79 self.method,
80 reqwest::Url::parse(&self.config.url)
81 .unwrap()
82 .join(&self.endpoint)
83 .unwrap(),
84 );
85
86 if let Some(p) = &self.payload {
88 req_builder = req_builder.json(p);
89 }
90
91 if let Some(auth) = self.auth {
93 req_builder = req_builder.header(
94 "Authorization",
95 format!("{} {}", auth.auth_type, auth.payload),
96 );
97 }
98
99 let r = req_builder.send().await.map_err(Error::Request)?;
101 let status = r.status().as_u16();
102 if status != 200 {
103 return Err(Error::HTTPNotOk(status));
104 }
105
106 let headers = r.headers();
107 if !headers.contains_key(HEADER_RESPONSE_STATUS)
108 || !headers.contains_key(HEADER_RESPONSE_MESSAGE)
109 {
110 return Err(Error::InvalidHeaders);
111 }
112
113 let msg = headers
114 .get(HEADER_RESPONSE_MESSAGE)
115 .unwrap()
116 .to_str()
117 .unwrap()
118 .to_string();
119
120 let status: u8 = headers
121 .get(HEADER_RESPONSE_STATUS)
122 .unwrap()
123 .to_str()
124 .unwrap()
125 .parse()
126 .map_err(|_| Error::InvalidHeaders)?;
127
128 Ok((r, msg, status))
129 }
130
131 pub async fn do_request_void(self) -> Result<(), Error> {
133 let (_, msg, status) = self.prepare_response().await?;
134
135 if status == STATUS_SUCCESS {
136 Ok(())
137 } else {
138 Err(Error::Error(msg))
139 }
140 }
141
142 pub async fn do_request<U>(self) -> Result<RequestResult<U>, Error>
144 where
145 U: DeserializeOwned,
146 {
147 let (r, msg, status) = self.prepare_response().await?;
148
149 if status == STATUS_SUCCESS {
150 let response: U = r.json().await.map_err(Error::Decode)?;
151
152 Ok(RequestResult {
153 response: Some(response),
154 message: msg.to_string(),
155 status_code: status,
156 })
157 } else {
158 Err(Error::Error(msg))
159 }
160 }
161}
162
163#[derive(Debug)]
167pub struct RequestResult<T>
168where
169 T: DeserializeOwned,
170{
171 pub response: Option<T>,
172 pub message: String,
173 pub status_code: u8,
174}
175
176#[derive(Default, Serialize)]
178pub struct ListJobs {
179 #[serde(rename(serialize = "l"))]
180 pub limit: i32,
181}
182
183#[derive(Default, Serialize)]
186pub struct JobRequest {
187 #[serde(rename(serialize = "id"))]
188 pub job_id: u32,
189}
190
191#[derive(Default, Serialize)]
194pub struct AddJobRequest {
195 #[serde(rename(serialize = "buildtype"))]
196 pub job_type: jobs::Type,
197
198 pub args: HashMap<String, String>,
199
200 #[serde(rename(serialize = "uploadtype"))]
201 pub upload_type: jobs::UploadType,
202
203 #[serde(rename(serialize = "disableccache"))]
204 pub disable_ccache: bool,
205}
206
207#[derive(Serialize, Debug, Default)]
210pub struct Credential {
211 #[serde(rename(serialize = "mid"))]
212 pub machine_id: String,
213
214 pub username: String,
215
216 #[serde(rename(serialize = "pass"))]
217 pub password: String,
218}