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 enum LocalAsyncRequestBody<'a, W> {
127 Empty,
129 Fixed(Bytes),
131 Streaming(BoxLocalAsyncWriteBody<'a, W>),
133}
134
135pub trait Client {
137 type BodyWriter;
139 type ResponseBody: Iterator<Item = Result<Bytes, Error>>;
141
142 fn send(
150 &self,
151 req: Request<RequestBody<'_, Self::BodyWriter>>,
152 ) -> Result<Response<Self::ResponseBody>, Error>;
153}
154
155pub trait AsyncClient {
157 type BodyWriter;
159 type ResponseBody: Stream<Item = Result<Bytes, Error>>;
161
162 fn send(
171 &self,
172 req: Request<AsyncRequestBody<'_, Self::BodyWriter>>,
173 ) -> impl Future<Output = Result<Response<Self::ResponseBody>, Error>> + Send;
174}
175
176pub trait LocalAsyncClient {
178 type BodyWriter;
180 type ResponseBody: Stream<Item = Result<Bytes, Error>>;
182
183 fn send(
192 &self,
193 req: Request<LocalAsyncRequestBody<'_, Self::BodyWriter>>,
194 ) -> impl Future<Output = Result<Response<Self::ResponseBody>, Error>>;
195}
196
197pub trait WriteBody<W> {
199 fn write_body(&mut self, w: &mut W) -> Result<(), Error>;
203
204 fn reset(&mut self) -> bool;
208}
209
210impl<W> WriteBody<W> for &[u8]
211where
212 W: Write,
213{
214 fn write_body(&mut self, w: &mut W) -> Result<(), Error> {
215 w.write_all(self).map_err(Error::internal_safe)
216 }
217
218 fn reset(&mut self) -> bool {
219 true
220 }
221}
222
223pub trait AsyncWriteBody<W> {
249 fn write_body(
253 self: Pin<&mut Self>,
254 w: Pin<&mut W>,
255 ) -> impl Future<Output = Result<(), Error>> + Send;
256
257 fn reset(self: Pin<&mut Self>) -> impl Future<Output = bool> + Send;
261}
262
263trait AsyncWriteBodyEraser<W> {
265 fn write_body<'a>(
266 self: Pin<&'a mut Self>,
267 w: Pin<&'a mut W>,
268 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>;
269
270 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
271 where
272 W: 'a;
273}
274
275impl<T, W> AsyncWriteBodyEraser<W> for T
276where
277 T: AsyncWriteBody<W> + ?Sized,
278{
279 fn write_body<'a>(
280 self: Pin<&'a mut Self>,
281 w: Pin<&'a mut W>,
282 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>> {
283 Box::pin(self.write_body(w))
284 }
285
286 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
287 where
288 W: 'a,
289 {
290 Box::pin(self.reset())
291 }
292}
293
294pub struct BoxAsyncWriteBody<'a, W> {
296 inner: Pin<Box<dyn AsyncWriteBodyEraser<W> + Send + 'a>>,
297}
298
299impl<'a, W> BoxAsyncWriteBody<'a, W> {
300 pub fn new<T>(v: T) -> Self
302 where
303 T: AsyncWriteBody<W> + Send + 'a,
304 {
305 BoxAsyncWriteBody { inner: Box::pin(v) }
306 }
307}
308
309impl<W> AsyncWriteBody<W> for BoxAsyncWriteBody<'_, W>
310where
311 W: Send,
312{
313 async fn write_body(mut self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error> {
314 self.inner.as_mut().write_body(w).await
315 }
316
317 async fn reset(mut self: Pin<&mut Self>) -> bool {
318 self.inner.as_mut().reset().await
319 }
320}
321
322pub trait LocalAsyncWriteBody<W> {
348 fn write_body(self: Pin<&mut Self>, w: Pin<&mut W>) -> impl Future<Output = Result<(), Error>>;
352
353 fn reset(self: Pin<&mut Self>) -> impl Future<Output = bool>;
357}
358
359trait LocalAsyncWriteBodyEraser<W> {
361 fn write_body<'a>(
362 self: Pin<&'a mut Self>,
363 w: Pin<&'a mut W>,
364 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>>;
365
366 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + 'a>>
367 where
368 W: 'a;
369}
370
371impl<T, W> LocalAsyncWriteBodyEraser<W> for T
372where
373 T: LocalAsyncWriteBody<W> + ?Sized,
374{
375 fn write_body<'a>(
376 self: Pin<&'a mut Self>,
377 w: Pin<&'a mut W>,
378 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>> {
379 Box::pin(self.write_body(w))
380 }
381
382 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + 'a>>
383 where
384 W: 'a,
385 {
386 Box::pin(self.reset())
387 }
388}
389
390pub struct BoxLocalAsyncWriteBody<'a, W> {
392 inner: Pin<Box<dyn LocalAsyncWriteBodyEraser<W> + 'a>>,
393}
394
395impl<'a, W> BoxLocalAsyncWriteBody<'a, W> {
396 pub fn new<T>(v: T) -> Self
398 where
399 T: LocalAsyncWriteBody<W> + 'a,
400 {
401 BoxLocalAsyncWriteBody { inner: Box::pin(v) }
402 }
403}
404
405impl<W> LocalAsyncWriteBody<W> for BoxLocalAsyncWriteBody<'_, W> {
406 async fn write_body(mut self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error> {
407 self.inner.as_mut().write_body(w).await
408 }
409
410 async fn reset(mut self: Pin<&mut Self>) -> bool {
411 self.inner.as_mut().reset().await
412 }
413}
414
415pub trait SerializeRequest<'a, T, W> {
418 fn content_type(value: &T) -> HeaderValue;
420
421 fn content_length(value: &T) -> Option<u64> {
427 let _value = value;
428 None
429 }
430
431 fn serialize(value: T) -> Result<RequestBody<'a, W>, Error>;
433}
434
435pub trait AsyncSerializeRequest<'a, T, W> {
438 fn content_type(value: &T) -> HeaderValue;
440
441 fn content_length(value: &T) -> Option<u64> {
447 let _value = value;
448 None
449 }
450
451 fn serialize(value: T) -> Result<AsyncRequestBody<'a, W>, Error>;
453}
454
455pub trait LocalAsyncSerializeRequest<'a, T, W> {
458 fn content_type(value: &T) -> HeaderValue;
460
461 fn content_length(value: &T) -> Option<u64> {
467 let _value = value;
468 None
469 }
470
471 fn serialize(value: T) -> Result<LocalAsyncRequestBody<'a, W>, Error>;
473}
474
475pub enum ConjureRequestSerializer {}
477
478impl<'a, T, W> SerializeRequest<'a, T, W> for ConjureRequestSerializer
479where
480 T: Serialize,
481{
482 fn content_type(_: &T) -> HeaderValue {
483 APPLICATION_JSON
484 }
485
486 fn serialize(value: T) -> Result<RequestBody<'a, W>, Error> {
487 let body = json::to_vec(&value).map_err(Error::internal)?;
488 Ok(RequestBody::Fixed(body.into()))
489 }
490}
491
492impl<'a, T, W> AsyncSerializeRequest<'a, T, W> for ConjureRequestSerializer
493where
494 T: Serialize,
495{
496 fn content_type(_: &T) -> HeaderValue {
497 APPLICATION_JSON
498 }
499
500 fn serialize(value: T) -> Result<AsyncRequestBody<'a, W>, Error> {
501 let buf = json::to_vec(&value).map_err(Error::internal)?;
502 Ok(AsyncRequestBody::Fixed(Bytes::from(buf)))
503 }
504}
505
506impl<'a, T, W> LocalAsyncSerializeRequest<'a, T, W> for ConjureRequestSerializer
507where
508 T: Serialize,
509{
510 fn content_type(_: &T) -> HeaderValue {
511 APPLICATION_JSON
512 }
513
514 fn serialize(value: T) -> Result<LocalAsyncRequestBody<'a, W>, Error> {
515 let buf = json::to_vec(&value).map_err(Error::internal)?;
516 Ok(LocalAsyncRequestBody::Fixed(Bytes::from(buf)))
517 }
518}
519
520pub trait DeserializeResponse<T, R> {
523 fn accept() -> Option<HeaderValue>;
525
526 fn deserialize(response: Response<R>) -> Result<T, Error>;
528}
529
530pub trait AsyncDeserializeResponse<T, R> {
533 fn accept() -> Option<HeaderValue>;
535
536 fn deserialize(response: Response<R>) -> impl Future<Output = Result<T, Error>> + Send;
538}
539
540pub trait LocalAsyncDeserializeResponse<T, R> {
543 fn accept() -> Option<HeaderValue>;
545
546 fn deserialize(response: Response<R>) -> impl Future<Output = Result<T, Error>>;
548}
549
550pub enum UnitResponseDeserializer {}
552
553impl<R> DeserializeResponse<(), R> for UnitResponseDeserializer {
554 fn accept() -> Option<HeaderValue> {
555 None
556 }
557
558 fn deserialize(_: Response<R>) -> Result<(), Error> {
559 Ok(())
560 }
561}
562
563impl<R> AsyncDeserializeResponse<(), R> for UnitResponseDeserializer
564where
565 R: Send,
566{
567 fn accept() -> Option<HeaderValue> {
568 None
569 }
570
571 async fn deserialize(_: Response<R>) -> Result<(), Error> {
572 Ok(())
573 }
574}
575
576impl<R> LocalAsyncDeserializeResponse<(), R> for UnitResponseDeserializer {
577 fn accept() -> Option<HeaderValue> {
578 None
579 }
580
581 async fn deserialize(_: Response<R>) -> Result<(), Error> {
582 Ok(())
583 }
584}
585
586pub enum ConjureResponseDeserializer {}
588
589impl<T, R> DeserializeResponse<T, R> for ConjureResponseDeserializer
590where
591 T: DeserializeOwned,
592 R: Iterator<Item = Result<Bytes, Error>>,
593{
594 fn accept() -> Option<HeaderValue> {
595 Some(APPLICATION_JSON)
596 }
597
598 fn deserialize(response: Response<R>) -> Result<T, Error> {
599 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
600 return Err(Error::internal_safe("invalid response Content-Type"));
601 }
602 let buf = private::read_body(response.into_body(), None)?;
603 json::client_from_slice(&buf).map_err(Error::internal)
604 }
605}
606
607impl<T, R> AsyncDeserializeResponse<T, R> for ConjureResponseDeserializer
608where
609 T: DeserializeOwned,
610 R: Stream<Item = Result<Bytes, Error>> + Send,
611{
612 fn accept() -> Option<HeaderValue> {
613 Some(APPLICATION_JSON)
614 }
615
616 async fn deserialize(response: Response<R>) -> Result<T, Error> {
617 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
618 return Err(Error::internal_safe("invalid response Content-Type"));
619 }
620 let buf = private::async_read_body(response.into_body(), None).await?;
621 json::client_from_slice(&buf).map_err(Error::internal)
622 }
623}
624
625impl<T, R> LocalAsyncDeserializeResponse<T, R> for ConjureResponseDeserializer
626where
627 T: DeserializeOwned,
628 R: Stream<Item = Result<Bytes, Error>>,
629{
630 fn accept() -> Option<HeaderValue> {
631 Some(APPLICATION_JSON)
632 }
633
634 async fn deserialize(response: Response<R>) -> Result<T, Error> {
635 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
636 return Err(Error::internal_safe("invalid response Content-Type"));
637 }
638 let buf = private::async_read_body(response.into_body(), None).await?;
639 json::client_from_slice(&buf).map_err(Error::internal)
640 }
641}
642
643pub trait EncodeHeader<T> {
645 fn encode(value: T) -> Result<Vec<HeaderValue>, Error>;
649}
650
651pub trait EncodeParam<T> {
654 fn encode(value: T) -> Result<Vec<String>, Error>;
660}
661
662pub enum DisplayEncoder {}
664
665impl<T> EncodeHeader<T> for DisplayEncoder
666where
667 T: Display,
668{
669 fn encode(value: T) -> Result<Vec<HeaderValue>, Error> {
670 HeaderValue::try_from(value.to_string())
671 .map_err(Error::internal_safe)
672 .map(|v| vec![v])
673 }
674}
675
676impl<T> EncodeParam<T> for DisplayEncoder
677where
678 T: Display,
679{
680 fn encode(value: T) -> Result<Vec<String>, Error> {
681 Ok(vec![value.to_string()])
682 }
683}
684
685pub enum DisplaySeqEncoder {}
688
689impl<T, U> EncodeHeader<T> for DisplaySeqEncoder
690where
691 T: IntoIterator<Item = U>,
692 U: Display,
693{
694 fn encode(value: T) -> Result<Vec<HeaderValue>, Error> {
695 value
696 .into_iter()
697 .map(|v| HeaderValue::try_from(v.to_string()).map_err(Error::internal_safe))
698 .collect()
699 }
700}
701
702impl<T, U> EncodeParam<T> for DisplaySeqEncoder
703where
704 T: IntoIterator<Item = U>,
705 U: Display,
706{
707 fn encode(value: T) -> Result<Vec<String>, Error> {
708 Ok(value.into_iter().map(|v| v.to_string()).collect())
709 }
710}