bitwarden_api_base/
request.rs1use http::header::CONTENT_TYPE;
2use serde::de::{DeserializeOwned, Error as _};
3
4use crate::{ContentType, Error, ResponseContent};
5
6fn content_type(response: &reqwest::Response) -> ContentType {
7 response
8 .headers()
9 .get(CONTENT_TYPE)
10 .and_then(|v| v.to_str().ok())
11 .unwrap_or("application/octet-stream")
12 .into()
13}
14
15#[inline(never)]
19async fn process_with_json_response_internal<E>(
20 request: reqwest_middleware::RequestBuilder,
21) -> Result<String, crate::Error<E>> {
22 let response = request.send().await?;
23 let status = response.status();
24 let content_type = content_type(&response);
25 let content = response.text().await?;
26
27 if !status.is_client_error() && !status.is_server_error() {
28 match content_type {
29 ContentType::Json => Ok(content),
30 ct => Err(Error::from(serde_json::Error::custom(format!(
31 "Received `{ct:?}` content type response when JSON was expected"
32 )))),
33 }
34 } else {
35 Err(Error::ResponseError(ResponseContent {
36 status,
37 content,
38 entity: None,
39 }))
40 }
41}
42
43pub async fn process_with_json_response<T: DeserializeOwned, E>(
45 request: reqwest_middleware::RequestBuilder,
46) -> Result<T, crate::Error<E>> {
47 process_with_json_response_internal(request)
48 .await
49 .and_then(|content| serde_json::from_str(&content).map_err(Into::into))
50}
51
52#[inline(never)]
54pub async fn process_with_empty_response<E>(
55 request: reqwest_middleware::RequestBuilder,
56) -> Result<(), crate::Error<E>> {
57 let response = request.send().await?;
58 let status = response.status();
59
60 if !status.is_client_error() && !status.is_server_error() {
61 Ok(())
62 } else {
63 let content = response.text().await?;
64 Err(Error::ResponseError(ResponseContent {
65 status,
66 content,
67 entity: None,
68 }))
69 }
70}