1use crate::private::{self, APPLICATION_JSON};
18use bytes::Bytes;
19use conjure_error::Error;
20use conjure_serde::json;
21use futures_core::Stream;
22use http::header::CONTENT_TYPE;
23use http::{HeaderValue, Request, Response};
24use serde::de::DeserializeOwned;
25use serde::Serialize;
26use std::convert::TryFrom;
27use std::fmt::Display;
28use std::future::Future;
29use std::io::Write;
30use std::pin::Pin;
31
32#[allow(missing_docs)]
33#[deprecated(note = "renamed to RequestBody", since = "3.5.0")]
34pub type Body<'a, T> = RequestBody<'a, T>;
35
36#[allow(missing_docs)]
37#[deprecated(note = "renamed to AsyncRequestBody", since = "3.5.0")]
38pub type AsyncBody<'a, T> = AsyncRequestBody<'a, T>;
39
40pub trait Service<C> {
42 fn new(client: C) -> Self;
44}
45
46pub trait AsyncService<C> {
48 fn new(client: C) -> Self;
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct Endpoint {
57 service: &'static str,
58 version: Option<&'static str>,
59 name: &'static str,
60 path: &'static str,
61}
62
63impl Endpoint {
64 #[inline]
66 pub fn new(
67 service: &'static str,
68 version: Option<&'static str>,
69 name: &'static str,
70 path: &'static str,
71 ) -> Self {
72 Endpoint {
73 service,
74 version,
75 name,
76 path,
77 }
78 }
79
80 #[inline]
82 pub fn service(&self) -> &'static str {
83 self.service
84 }
85
86 #[inline]
88 pub fn version(&self) -> Option<&'static str> {
89 self.version
90 }
91
92 #[inline]
94 pub fn name(&self) -> &'static str {
95 self.name
96 }
97
98 #[inline]
100 pub fn path(&self) -> &'static str {
101 self.path
102 }
103}
104
105pub enum RequestBody<'a, W> {
107 Empty,
109 Fixed(Bytes),
111 Streaming(Box<dyn WriteBody<W> + 'a>),
113}
114
115pub enum AsyncRequestBody<'a, W> {
117 Empty,
119 Fixed(Bytes),
121 Streaming(BoxAsyncWriteBody<'a, W>),
123}
124
125pub trait Client {
127 type BodyWriter;
129 type ResponseBody: Iterator<Item = Result<Bytes, Error>>;
131
132 fn send(
140 &self,
141 req: Request<RequestBody<'_, Self::BodyWriter>>,
142 ) -> Result<Response<Self::ResponseBody>, Error>;
143}
144
145pub trait AsyncClient {
147 type BodyWriter;
149 type ResponseBody: Stream<Item = Result<Bytes, Error>>;
151
152 fn send(
161 &self,
162 req: Request<AsyncRequestBody<'_, Self::BodyWriter>>,
163 ) -> impl Future<Output = Result<Response<Self::ResponseBody>, Error>> + Send;
164}
165
166pub trait WriteBody<W> {
168 fn write_body(&mut self, w: &mut W) -> Result<(), Error>;
172
173 fn reset(&mut self) -> bool;
177}
178
179impl<W> WriteBody<W> for &[u8]
180where
181 W: Write,
182{
183 fn write_body(&mut self, w: &mut W) -> Result<(), Error> {
184 w.write_all(self).map_err(Error::internal_safe)
185 }
186
187 fn reset(&mut self) -> bool {
188 true
189 }
190}
191
192pub trait AsyncWriteBody<W> {
218 fn write_body(
222 self: Pin<&mut Self>,
223 w: Pin<&mut W>,
224 ) -> impl Future<Output = Result<(), Error>> + Send;
225
226 fn reset(self: Pin<&mut Self>) -> impl Future<Output = bool> + Send;
230}
231
232trait AsyncWriteBodyEraser<W> {
234 fn write_body<'a>(
235 self: Pin<&'a mut Self>,
236 w: Pin<&'a mut W>,
237 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>;
238
239 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
240 where
241 W: 'a;
242}
243
244impl<T, W> AsyncWriteBodyEraser<W> for T
245where
246 T: AsyncWriteBody<W> + ?Sized,
247{
248 fn write_body<'a>(
249 self: Pin<&'a mut Self>,
250 w: Pin<&'a mut W>,
251 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>> {
252 Box::pin(self.write_body(w))
253 }
254
255 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
256 where
257 W: 'a,
258 {
259 Box::pin(self.reset())
260 }
261}
262
263pub struct BoxAsyncWriteBody<'a, W> {
265 inner: Pin<Box<dyn AsyncWriteBodyEraser<W> + Send + 'a>>,
266}
267
268impl<'a, W> BoxAsyncWriteBody<'a, W> {
269 pub fn new<T>(v: T) -> Self
271 where
272 T: AsyncWriteBody<W> + Send + 'a,
273 {
274 BoxAsyncWriteBody { inner: Box::pin(v) }
275 }
276}
277
278impl<W> AsyncWriteBody<W> for BoxAsyncWriteBody<'_, W>
279where
280 W: Send,
281{
282 async fn write_body(mut self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error> {
283 self.inner.as_mut().write_body(w).await
284 }
285
286 async fn reset(mut self: Pin<&mut Self>) -> bool {
287 self.inner.as_mut().reset().await
288 }
289}
290
291pub trait SerializeRequest<'a, T, W> {
294 fn content_type(value: &T) -> HeaderValue;
296
297 fn content_length(value: &T) -> Option<u64> {
303 let _value = value;
304 None
305 }
306
307 fn serialize(value: T) -> Result<RequestBody<'a, W>, Error>;
309}
310
311pub trait AsyncSerializeRequest<'a, T, W> {
314 fn content_type(value: &T) -> HeaderValue;
316
317 fn content_length(value: &T) -> Option<u64> {
323 let _value = value;
324 None
325 }
326
327 fn serialize(value: T) -> Result<AsyncRequestBody<'a, W>, Error>;
329}
330
331pub enum ConjureRequestSerializer {}
333
334impl<'a, T, W> SerializeRequest<'a, T, W> for ConjureRequestSerializer
335where
336 T: Serialize,
337{
338 fn content_type(_: &T) -> HeaderValue {
339 APPLICATION_JSON
340 }
341
342 fn serialize(value: T) -> Result<RequestBody<'a, W>, Error> {
343 let body = json::to_vec(&value).map_err(Error::internal)?;
344 Ok(RequestBody::Fixed(body.into()))
345 }
346}
347
348impl<'a, T, W> AsyncSerializeRequest<'a, T, W> for ConjureRequestSerializer
349where
350 T: Serialize,
351{
352 fn content_type(_: &T) -> HeaderValue {
353 APPLICATION_JSON
354 }
355
356 fn serialize(value: T) -> Result<AsyncRequestBody<'a, W>, Error> {
357 let buf = json::to_vec(&value).map_err(Error::internal)?;
358 Ok(AsyncRequestBody::Fixed(Bytes::from(buf)))
359 }
360}
361
362pub trait DeserializeResponse<T, R> {
365 fn accept() -> Option<HeaderValue>;
367
368 fn deserialize(response: Response<R>) -> Result<T, Error>;
370}
371
372pub trait AsyncDeserializeResponse<T, R> {
375 fn accept() -> Option<HeaderValue>;
377
378 fn deserialize(response: Response<R>) -> impl Future<Output = Result<T, Error>> + Send;
380}
381
382pub enum UnitResponseDeserializer {}
384
385impl<R> DeserializeResponse<(), R> for UnitResponseDeserializer {
386 fn accept() -> Option<HeaderValue> {
387 None
388 }
389
390 fn deserialize(_: Response<R>) -> Result<(), Error> {
391 Ok(())
392 }
393}
394
395impl<R> AsyncDeserializeResponse<(), R> for UnitResponseDeserializer
396where
397 R: Send,
398{
399 fn accept() -> Option<HeaderValue> {
400 None
401 }
402
403 async fn deserialize(_: Response<R>) -> Result<(), Error> {
404 Ok(())
405 }
406}
407
408pub enum ConjureResponseDeserializer {}
410
411impl<T, R> DeserializeResponse<T, R> for ConjureResponseDeserializer
412where
413 T: DeserializeOwned,
414 R: Iterator<Item = Result<Bytes, Error>>,
415{
416 fn accept() -> Option<HeaderValue> {
417 Some(APPLICATION_JSON)
418 }
419
420 fn deserialize(response: Response<R>) -> Result<T, Error> {
421 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
422 return Err(Error::internal_safe("invalid response Content-Type"));
423 }
424 let buf = private::read_body(response.into_body(), None)?;
425 json::client_from_slice(&buf).map_err(Error::internal)
426 }
427}
428
429impl<T, R> AsyncDeserializeResponse<T, R> for ConjureResponseDeserializer
430where
431 T: DeserializeOwned,
432 R: Stream<Item = Result<Bytes, Error>> + Send,
433{
434 fn accept() -> Option<HeaderValue> {
435 Some(APPLICATION_JSON)
436 }
437
438 async fn deserialize(response: Response<R>) -> Result<T, Error> {
439 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
440 return Err(Error::internal_safe("invalid response Content-Type"));
441 }
442 let buf = private::async_read_body(response.into_body(), None).await?;
443 json::client_from_slice(&buf).map_err(Error::internal)
444 }
445}
446
447pub trait EncodeHeader<T> {
449 fn encode(value: T) -> Result<Vec<HeaderValue>, Error>;
453}
454
455pub trait EncodeParam<T> {
458 fn encode(value: T) -> Result<Vec<String>, Error>;
464}
465
466pub enum DisplayEncoder {}
468
469impl<T> EncodeHeader<T> for DisplayEncoder
470where
471 T: Display,
472{
473 fn encode(value: T) -> Result<Vec<HeaderValue>, Error> {
474 HeaderValue::try_from(value.to_string())
475 .map_err(Error::internal_safe)
476 .map(|v| vec![v])
477 }
478}
479
480impl<T> EncodeParam<T> for DisplayEncoder
481where
482 T: Display,
483{
484 fn encode(value: T) -> Result<Vec<String>, Error> {
485 Ok(vec![value.to_string()])
486 }
487}
488
489pub enum DisplaySeqEncoder {}
492
493impl<T, U> EncodeHeader<T> for DisplaySeqEncoder
494where
495 T: IntoIterator<Item = U>,
496 U: Display,
497{
498 fn encode(value: T) -> Result<Vec<HeaderValue>, Error> {
499 value
500 .into_iter()
501 .map(|v| HeaderValue::try_from(v.to_string()).map_err(Error::internal_safe))
502 .collect()
503 }
504}
505
506impl<T, U> EncodeParam<T> for DisplaySeqEncoder
507where
508 T: IntoIterator<Item = U>,
509 U: Display,
510{
511 fn encode(value: T) -> Result<Vec<String>, Error> {
512 Ok(value.into_iter().map(|v| v.to_string()).collect())
513 }
514}