1use crate::error::ApiError;
4
5use fire::header::{HeaderValues, Method, Mime, StatusCode};
6use fire::resources::Resources;
7use fire::routes::ParamsNames;
8use fire::{Body, Error, FirePit, Request, Response};
9
10use representation::request::DeserializeError;
11use serde::de::DeserializeOwned;
12
13pub struct FirePitApi {
14 inner: FirePit,
15}
16
17impl FirePitApi {
18 pub fn new(inner: FirePit) -> Self {
19 Self { inner }
20 }
21
22 pub fn data(&self) -> &Resources {
23 self.inner.data()
24 }
25
26 pub async fn route(
32 &self,
33 req: &mut Request,
34 ) -> Option<Result<Response, Error>> {
35 self.inner.route(req).await
36 }
37
38 pub async fn request<R>(&self, req: &R) -> Result<R::Response, R::Error>
39 where
40 R: crate::Request,
41 R::Error: DeserializeOwned + Send + 'static,
42 R::Response: Send + 'static,
43 {
44 let params = ParamsNames::parse(R::PATH);
45 assert!(params.is_empty(), "path parameters are not allowed");
46
47 self.request_with_header(R::PATH, req, HeaderValues::new())
48 .await
49 }
50
51 pub async fn request_with_uri<R>(
52 &self,
53 uri: impl AsRef<str>,
54 req: &R,
55 ) -> Result<R::Response, R::Error>
56 where
57 R: crate::Request,
58 R::Error: DeserializeOwned + Send + 'static,
59 R::Response: Send + 'static,
60 {
61 self.request_with_header(uri.as_ref(), req, HeaderValues::new())
62 .await
63 }
64
65 pub async fn request_with_header<R>(
66 &self,
67 uri: impl AsRef<str>,
68 req: &R,
69 header: HeaderValues,
70 ) -> Result<R::Response, R::Error>
71 where
72 R: crate::Request,
73 R::Error: DeserializeOwned + Send + 'static,
74 R::Response: Send + 'static,
75 {
76 let mut raw_req =
77 Request::builder(uri.as_ref().parse().unwrap()).method(R::METHOD);
78 *raw_req.values_mut() = header;
79
80 let mut req = if R::METHOD == &Method::GET {
81 raw_req.serialize_query(req).unwrap().build()
82 } else {
83 raw_req
84 .content_type(Mime::JSON)
85 .body(Body::serialize(req).unwrap())
86 .build()
87 };
88
89 self.request_raw::<R>(&mut req).await
90 }
91
92 pub async fn request_raw<R>(
93 &self,
94 req: &mut Request,
95 ) -> Result<R::Response, R::Error>
96 where
97 R: crate::Request,
98 R::Error: DeserializeOwned + Send + 'static,
99 R::Response: Send + 'static,
100 {
101 let mut resp = self
102 .route(req)
103 .await
104 .unwrap()
105 .map_err(crate::error::Error::Fire)
106 .map_err(R::Error::from_error)?;
107
108 if resp.header().status_code() != &StatusCode::OK {
109 let e = resp
110 .body
111 .deserialize()
112 .await
113 .map_err(DeserializeError::Json)
114 .map_err(crate::error::Error::Deserialize)
115 .map_err(R::Error::from_error)?;
116
117 return Err(e);
118 }
119
120 resp.take_body()
121 .deserialize()
122 .await
123 .map_err(DeserializeError::Json)
124 .map_err(crate::error::Error::Deserialize)
125 .map_err(R::Error::from_error)
126 }
127}