http_request_derive/
from_http_response.rs1use async_trait::async_trait;
6use bytes::Bytes;
7
8use crate::Error;
9
10#[async_trait]
12pub trait FromHttpResponse {
13 fn from_http_response(http_response: http::Response<Bytes>) -> Result<Self, Error>
24 where
25 Self: Sized;
26}
27
28#[cfg(feature = "serde")]
29#[async_trait]
30impl<D> FromHttpResponse for D
31where
32 D: serde::de::DeserializeOwned,
33{
34 fn from_http_response(http_response: http::Response<Bytes>) -> Result<Self, Error> {
35 use snafu::ResultExt as _;
36 serde_json::from_slice(http_response.body()).context(crate::error::JsonSnafu)
37 }
38}
39
40#[cfg(all(test, feature = "serde"))]
41mod serde_tests {
42 use http::StatusCode;
43 use serde::Deserialize;
44
45 use super::*;
46
47 #[derive(Deserialize, Debug, PartialEq)]
48 struct TestStruct {
49 id: i32,
50 name: String,
51 }
52
53 #[tokio::test]
54 async fn test_from_response_success() {
55 let response = http::Response::builder()
56 .status(StatusCode::OK)
57 .header("content-type", "application/json")
58 .body(Bytes::from_static(r#"{"id":1,"name":"Test"}"#.as_bytes()))
59 .expect("valid response required");
60
61 let result = TestStruct::from_http_response(response);
62 assert!(result.is_ok());
63 assert_eq!(
64 result.unwrap(),
65 TestStruct {
66 id: 1,
67 name: "Test".to_string()
68 }
69 );
70 }
71
72 #[tokio::test]
73 async fn test_from_response_invalid_json() {
74 let response = http::Response::builder()
75 .status(StatusCode::OK)
76 .header("content-type", "application/json")
77 .body(Bytes::from_static(r#"{"id":1,"name":"Test"#.as_bytes()))
78 .expect("valid response required");
79
80 let result = TestStruct::from_http_response(response);
81 assert!(result.is_err());
82 assert!(matches!(result.unwrap_err(), Error::Json { .. }));
83 }
84}