1use crate::{
4 enums::{RequestMethod, RequestType},
5 errors::ClientError,
6};
7use http::{Request, Uri};
8use serde::Serialize;
9use url::Url;
10
11#[instrument(skip(object), err)]
14pub fn build_body(object: &impl Serialize, ty: RequestType) -> Result<Vec<u8>, ClientError> {
15 match ty {
16 RequestType::JSON => {
17 let parse_data = serde_json::to_string(object)
18 .map_err(|e| ClientError::DataParseError { source: e.into() })?;
19 Ok(match parse_data.as_str() {
20 "null" => "".as_bytes().to_vec(),
21 "{}" => "".as_bytes().to_vec(),
22 _ => parse_data.as_bytes().to_vec(),
23 })
24 }
25 }
26}
27
28#[instrument(skip(object), err)]
30pub fn build_query(object: &impl Serialize) -> Result<String, ClientError> {
31 serde_urlencoded::to_string(object)
32 .map_err(|e| ClientError::UrlQueryParseError { source: e.into() })
33}
34
35#[instrument(skip(query, data), err)]
37pub fn build_request(
38 base: &str,
39 path: &str,
40 method: RequestMethod,
41 query: Option<String>,
42 data: Option<Vec<u8>>,
43) -> Result<Request<Vec<u8>>, ClientError> {
44 debug!("Building endpoint request");
45 let uri = build_url(base, path, query)?;
46
47 let method_err = method.clone();
48 let uri_err = uri.to_string();
49 Request::builder()
50 .uri(uri)
51 .method(method)
52 .body(data.unwrap_or_default())
53 .map_err(|e| ClientError::RequestBuildError {
54 source: e,
55 method: method_err,
56 url: uri_err,
57 })
58}
59
60#[instrument(skip(query), err)]
63pub fn build_url(base: &str, path: &str, query: Option<String>) -> Result<Uri, ClientError> {
64 let mut url = Url::parse(base).map_err(|e| ClientError::UrlParseError { source: e })?;
65 url.path_segments_mut().unwrap().extend(path.split('/'));
66 if let Some(q) = query {
67 url.set_query(Some(q.as_str()));
68 }
69
70 url.to_string()
71 .parse::<Uri>()
72 .map_err(|e| ClientError::UrlBuildError { source: e })
73}