dimo_rust_sdk/utils/
request.rs1use crate::utils::get_credentials;
2use reqwest::{Client, Method};
3use serde_json::Value;
4use std::collections::HashMap;
5use std::error::Error;
6
7#[derive(serde::Serialize)]
8pub enum QueryValue {
9 Str(String),
10 Bool(bool),
11}
12
13#[derive(Debug, serde::Serialize)]
14pub enum BodyValue {
15 String(String),
16 Array(Vec<String>),
17}
18
19#[derive(Debug)]
20pub struct RequestParams {
21 pub method: Method,
22 pub base_url: String,
23 pub path: String,
24 pub query_params: Option<HashMap<String, String>>,
25 pub body: Option<HashMap<String, Value>>,
26 pub headers: Option<HashMap<String, String>>,
27}
28
29pub struct AuthRequestParams {
30 pub method: Method,
31 pub base_url: String,
32 pub path: String,
33 pub query_params: Option<HashMap<String, String>>,
34 pub body: Option<HashMap<String, Value>>,
35 pub headers: Option<HashMap<String, String>>,
36 pub token_type: String,
37}
38
39fn build_auth_header(token_type: &str) -> Result<HashMap<String, String>, Box<dyn Error>> {
42 let credentials = get_credentials()?;
43
44 let token = match token_type {
45 "developer" => &credentials.developer_jwt,
46 "vehicle" => &credentials.vehicle_jwt,
47 _ => return Err("Invalid token type specified. Use 'developer' or 'vehicle'.".into()),
48 };
49
50 let mut headers = HashMap::new();
51 headers.insert("Authorization".to_string(), format!("Bearer {}", token));
52 Ok(headers)
53}
54
55pub async fn make_auth_request(params: AuthRequestParams) -> Result<Value, Box<dyn Error>> {
56 let auth_header = build_auth_header(¶ms.token_type)?;
57 let mut headers = params.headers.unwrap_or_default();
58 headers.extend(auth_header);
59
60 let request_params = RequestParams {
61 method: params.method,
62 base_url: params.base_url,
63 path: params.path,
64 query_params: params.query_params,
65 body: params.body,
66 headers: Some(headers),
67 };
68
69 make_request(request_params).await
70}
71
72pub async fn make_request(params: RequestParams) -> Result<Value, Box<dyn Error>> {
73 let client = Client::new();
74 let url = format!("{}{}", params.base_url, params.path);
75
76 let mut request_builder = match params.method {
77 Method::GET => client.get(&url),
78 Method::POST => client.post(&url),
79 Method::PATCH => client.patch(&url),
80 _ => return Err("Unsupported method".into()),
81 };
82
83 if let Some(ref query_params) = params.query_params {
84 request_builder = request_builder.query(&query_params);
85 };
86
87 let use_form_body = params
88 .headers
89 .as_ref()
90 .and_then(|headers| headers.get("Content-Type"))
91 .map(|value| value.eq_ignore_ascii_case("x-www-form-urlencoded"))
92 .unwrap_or(false);
93
94 if let Some(body) = params.body {
95 request_builder = if use_form_body {
96 request_builder.form(&body)
97 } else {
98 request_builder.json(&body)
99 };
100 }
101
102 if let Some(headers) = params.headers {
103 for (key, value) in headers {
104 request_builder = request_builder.header(&key, &value);
105 }
106 }
107
108 let response_result = request_builder.send().await;
109
110 match response_result {
111 Ok(resp) => {
112 if resp.status().is_success() {
113 let json_response = resp.json::<Value>().await?;
114 Ok(json_response)
115 } else {
116 let status = resp.status();
117 let error_text = resp
118 .text()
119 .await
120 .unwrap_or_else(|_| "Unknown error".to_string());
121 Err(format!("Error {}: {}", status, error_text).into())
122 }
123 }
124 Err(err) => Err(format!("Request error: {}", err).into()),
125 }
126}