1use std::convert::TryFrom;
18
19use bytes::Bytes;
20use conjure_error::Error;
21use conjure_object::{Plain, ToPlain};
22use futures_core::Stream;
23use http::{header::CONTENT_TYPE, HeaderValue, Response, StatusCode};
24use serde::de::{DeserializeOwned, IgnoredAny};
25
26use crate::client::{
27 AsyncDeserializeResponse, AsyncRequestBody, AsyncSerializeRequest, AsyncWriteBody,
28 BoxAsyncWriteBody, BoxLocalAsyncWriteBody, ConjureRuntime, DeserializeResponse, EncodeHeader,
29 EncodeParam, LocalAsyncDeserializeResponse, LocalAsyncRequestBody, LocalAsyncSerializeRequest,
30 LocalAsyncWriteBody, RequestBody, SerializeRequest, StdResponseDeserializer, WriteBody,
31};
32use crate::private::APPLICATION_OCTET_STREAM;
33
34pub enum BinaryRequestSerializer {}
36
37impl<'a, T, R> SerializeRequest<'a, T, R> for BinaryRequestSerializer
38where
39 T: WriteBody<R> + 'a,
40{
41 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
42 APPLICATION_OCTET_STREAM
43 }
44
45 fn serialize(_: &ConjureRuntime, value: T) -> Result<RequestBody<'a, R>, Error> {
46 Ok(RequestBody::Streaming(Box::new(value)))
47 }
48}
49
50impl<'a, T, R> AsyncSerializeRequest<'a, T, R> for BinaryRequestSerializer
51where
52 T: AsyncWriteBody<R> + Send + 'a,
53{
54 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
55 APPLICATION_OCTET_STREAM
56 }
57
58 fn serialize(_: &ConjureRuntime, value: T) -> Result<AsyncRequestBody<'a, R>, Error> {
59 Ok(AsyncRequestBody::Streaming(BoxAsyncWriteBody::new(value)))
60 }
61}
62
63impl<'a, T, R> LocalAsyncSerializeRequest<'a, T, R> for BinaryRequestSerializer
64where
65 T: LocalAsyncWriteBody<R> + 'a,
66{
67 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
68 APPLICATION_OCTET_STREAM
69 }
70
71 fn serialize(_: &ConjureRuntime, value: T) -> Result<LocalAsyncRequestBody<'a, R>, Error> {
72 Ok(LocalAsyncRequestBody::Streaming(
73 BoxLocalAsyncWriteBody::new(value),
74 ))
75 }
76}
77
78pub enum CollectionResponseDeserializer {}
80
81impl<T, R> DeserializeResponse<T, R> for CollectionResponseDeserializer
82where
83 T: DeserializeOwned + Default,
84 R: Iterator<Item = Result<Bytes, Error>>,
85{
86 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
87 <StdResponseDeserializer as DeserializeResponse<T, R>>::accept(runtime)
88 }
89
90 fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
91 if response.status() == StatusCode::NO_CONTENT {
92 return Ok(T::default());
93 }
94
95 <StdResponseDeserializer as DeserializeResponse<T, R>>::deserialize(runtime, response)
96 }
97}
98
99impl<T, R> AsyncDeserializeResponse<T, R> for CollectionResponseDeserializer
100where
101 T: DeserializeOwned + Default,
102 R: Stream<Item = Result<Bytes, Error>> + Send,
103{
104 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
105 <StdResponseDeserializer as AsyncDeserializeResponse<T, R>>::accept(runtime)
106 }
107
108 async fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
109 if response.status() == StatusCode::NO_CONTENT {
110 return Ok(T::default());
111 }
112
113 <StdResponseDeserializer as AsyncDeserializeResponse<T, R>>::deserialize(runtime, response)
114 .await
115 }
116}
117
118impl<T, R> LocalAsyncDeserializeResponse<T, R> for CollectionResponseDeserializer
119where
120 T: DeserializeOwned + Default,
121 R: Stream<Item = Result<Bytes, Error>>,
122{
123 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
124 <StdResponseDeserializer as LocalAsyncDeserializeResponse<T, R>>::accept(runtime)
125 }
126
127 async fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
128 if response.status() == StatusCode::NO_CONTENT {
129 return Ok(T::default());
130 }
131
132 <StdResponseDeserializer as LocalAsyncDeserializeResponse<T, R>>::deserialize(
133 runtime, response,
134 )
135 .await
136 }
137}
138
139pub enum BinaryResponseDeserializer {}
141
142impl<R> DeserializeResponse<R, R> for BinaryResponseDeserializer {
143 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
144 Some(APPLICATION_OCTET_STREAM)
145 }
146
147 fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<R, Error> {
148 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_OCTET_STREAM) {
149 return Err(Error::internal_safe("invalid response Content-Type"));
150 }
151
152 Ok(response.into_body())
153 }
154}
155
156impl<R> AsyncDeserializeResponse<R, R> for BinaryResponseDeserializer
157where
158 R: Send,
159{
160 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
161 Some(APPLICATION_OCTET_STREAM)
162 }
163
164 async fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<R, Error> {
165 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_OCTET_STREAM) {
166 return Err(Error::internal_safe("invalid response Content-Type"));
167 }
168
169 Ok(response.into_body())
170 }
171}
172
173impl<R> LocalAsyncDeserializeResponse<R, R> for BinaryResponseDeserializer {
174 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
175 Some(APPLICATION_OCTET_STREAM)
176 }
177
178 async fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<R, Error> {
179 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_OCTET_STREAM) {
180 return Err(Error::internal_safe("invalid response Content-Type"));
181 }
182
183 Ok(response.into_body())
184 }
185}
186
187pub enum OptionalBinaryResponseDeserializer {}
189
190impl<R> DeserializeResponse<Option<R>, R> for OptionalBinaryResponseDeserializer {
191 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
192 <BinaryResponseDeserializer as DeserializeResponse<R, R>>::accept(runtime)
193 }
194
195 fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<Option<R>, Error> {
196 if response.status() == StatusCode::NO_CONTENT {
197 return Ok(None);
198 }
199
200 <BinaryResponseDeserializer as DeserializeResponse<R, R>>::deserialize(runtime, response)
201 .map(Some)
202 }
203}
204
205impl<R> AsyncDeserializeResponse<Option<R>, R> for OptionalBinaryResponseDeserializer
206where
207 R: Send,
208{
209 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
210 <BinaryResponseDeserializer as AsyncDeserializeResponse<R, R>>::accept(runtime)
211 }
212
213 async fn deserialize(
214 runtime: &ConjureRuntime,
215 response: Response<R>,
216 ) -> Result<Option<R>, Error> {
217 if response.status() == StatusCode::NO_CONTENT {
218 return Ok(None);
219 }
220
221 <BinaryResponseDeserializer as AsyncDeserializeResponse<R, R>>::deserialize(
222 runtime, response,
223 )
224 .await
225 .map(Some)
226 }
227}
228
229impl<R> LocalAsyncDeserializeResponse<Option<R>, R> for OptionalBinaryResponseDeserializer {
230 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
231 <BinaryResponseDeserializer as LocalAsyncDeserializeResponse<R, R>>::accept(runtime)
232 }
233
234 async fn deserialize(
235 runtime: &ConjureRuntime,
236 response: Response<R>,
237 ) -> Result<Option<R>, Error> {
238 if response.status() == StatusCode::NO_CONTENT {
239 return Ok(None);
240 }
241
242 <BinaryResponseDeserializer as LocalAsyncDeserializeResponse<R, R>>::deserialize(
243 runtime, response,
244 )
245 .await
246 .map(Some)
247 }
248}
249
250pub enum EmptyResponseDeserializer {}
252
253impl<R> DeserializeResponse<(), R> for EmptyResponseDeserializer
254where
255 R: Iterator<Item = Result<Bytes, Error>>,
256{
257 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
258 <StdResponseDeserializer as DeserializeResponse<(), R>>::accept(runtime)
259 }
260
261 fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<(), Error> {
262 if response.status() == StatusCode::NO_CONTENT {
263 return Ok(());
264 }
265
266 <StdResponseDeserializer as DeserializeResponse<IgnoredAny, R>>::deserialize(
267 runtime, response,
268 )?;
269
270 Ok(())
271 }
272}
273
274impl<R> AsyncDeserializeResponse<(), R> for EmptyResponseDeserializer
275where
276 R: Stream<Item = Result<Bytes, Error>> + Send,
277{
278 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
279 <StdResponseDeserializer as AsyncDeserializeResponse<(), R>>::accept(runtime)
280 }
281
282 async fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<(), Error> {
283 if response.status() == StatusCode::NO_CONTENT {
284 return Ok(());
285 }
286
287 <StdResponseDeserializer as AsyncDeserializeResponse<IgnoredAny, R>>::deserialize(
288 runtime, response,
289 )
290 .await?;
291
292 Ok(())
293 }
294}
295
296impl<R> LocalAsyncDeserializeResponse<(), R> for EmptyResponseDeserializer
297where
298 R: Stream<Item = Result<Bytes, Error>>,
299{
300 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue> {
301 <StdResponseDeserializer as LocalAsyncDeserializeResponse<(), R>>::accept(runtime)
302 }
303
304 async fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<(), Error> {
305 if response.status() == StatusCode::NO_CONTENT {
306 return Ok(());
307 }
308
309 <StdResponseDeserializer as LocalAsyncDeserializeResponse<IgnoredAny, R>>::deserialize(
310 runtime, response,
311 )
312 .await?;
313
314 Ok(())
315 }
316}
317
318pub enum PlainEncoder {}
320
321impl<T> EncodeParam<T> for PlainEncoder
322where
323 T: Plain,
324{
325 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<String>, Error> {
326 Ok(vec![value.to_plain()])
327 }
328}
329
330impl<T> EncodeHeader<T> for PlainEncoder
331where
332 T: Plain,
333{
334 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error> {
335 HeaderValue::try_from(value.to_plain())
336 .map_err(Error::internal_safe)
337 .map(|v| vec![v])
338 }
339}
340
341pub enum PlainSeqEncoder {}
343
344impl<T, U> EncodeParam<T> for PlainSeqEncoder
345where
346 T: IntoIterator<Item = U>,
347 U: Plain,
348{
349 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<String>, Error> {
350 Ok(value.into_iter().map(|v| v.to_plain()).collect())
351 }
352}
353
354impl<T, U> EncodeHeader<T> for PlainSeqEncoder
355where
356 T: IntoIterator<Item = U>,
357 U: Plain,
358{
359 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error> {
360 value
361 .into_iter()
362 .map(|v| HeaderValue::try_from(v.to_plain()).map_err(Error::internal_safe))
363 .collect()
364 }
365}