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::marker::PhantomData;
31use std::pin::Pin;
32use std::sync::Arc;
33
34pub mod conjure;
35
36pub trait Service<C> {
38 fn new(client: C, runtime: &Arc<ConjureRuntime>) -> Self;
40}
41
42pub trait AsyncService<C> {
44 fn new(client: C, runtime: &Arc<ConjureRuntime>) -> Self;
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct Endpoint {
53 service: &'static str,
54 version: Option<&'static str>,
55 name: &'static str,
56 path: &'static str,
57}
58
59impl Endpoint {
60 #[inline]
62 pub fn new(
63 service: &'static str,
64 version: Option<&'static str>,
65 name: &'static str,
66 path: &'static str,
67 ) -> Self {
68 Endpoint {
69 service,
70 version,
71 name,
72 path,
73 }
74 }
75
76 #[inline]
78 pub fn service(&self) -> &'static str {
79 self.service
80 }
81
82 #[inline]
84 pub fn version(&self) -> Option<&'static str> {
85 self.version
86 }
87
88 #[inline]
90 pub fn name(&self) -> &'static str {
91 self.name
92 }
93
94 #[inline]
96 pub fn path(&self) -> &'static str {
97 self.path
98 }
99}
100
101pub enum RequestBody<'a, W> {
103 Empty,
105 Fixed(Bytes),
107 Streaming(Box<dyn WriteBody<W> + 'a>),
109}
110
111pub enum AsyncRequestBody<'a, W> {
113 Empty,
115 Fixed(Bytes),
117 Streaming(BoxAsyncWriteBody<'a, W>),
119}
120
121pub enum LocalAsyncRequestBody<'a, W> {
123 Empty,
125 Fixed(Bytes),
127 Streaming(BoxLocalAsyncWriteBody<'a, W>),
129}
130
131pub trait Client {
133 type BodyWriter;
135 type ResponseBody: Iterator<Item = Result<Bytes, Error>>;
137
138 fn send(
146 &self,
147 req: Request<RequestBody<'_, Self::BodyWriter>>,
148 ) -> Result<Response<Self::ResponseBody>, Error>;
149}
150
151pub trait AsyncClient {
153 type BodyWriter;
155 type ResponseBody: Stream<Item = Result<Bytes, Error>>;
157
158 fn send(
167 &self,
168 req: Request<AsyncRequestBody<'_, Self::BodyWriter>>,
169 ) -> impl Future<Output = Result<Response<Self::ResponseBody>, Error>> + Send;
170}
171
172pub trait LocalAsyncClient {
174 type BodyWriter;
176 type ResponseBody: Stream<Item = Result<Bytes, Error>>;
178
179 fn send(
188 &self,
189 req: Request<LocalAsyncRequestBody<'_, Self::BodyWriter>>,
190 ) -> impl Future<Output = Result<Response<Self::ResponseBody>, Error>>;
191}
192
193#[derive(Debug)]
195pub struct ConjureRuntime(());
196
197impl ConjureRuntime {
198 pub fn new() -> Self {
200 ConjureRuntime(())
201 }
202}
203
204impl Default for ConjureRuntime {
205 fn default() -> Self {
206 Self::new()
207 }
208}
209
210pub trait WriteBody<W> {
212 fn write_body(&mut self, w: &mut W) -> Result<(), Error>;
216
217 fn reset(&mut self) -> bool;
221}
222
223impl<W> WriteBody<W> for &[u8]
224where
225 W: Write,
226{
227 fn write_body(&mut self, w: &mut W) -> Result<(), Error> {
228 w.write_all(self).map_err(Error::internal_safe)
229 }
230
231 fn reset(&mut self) -> bool {
232 true
233 }
234}
235
236pub trait AsyncWriteBody<W> {
262 fn write_body(
266 self: Pin<&mut Self>,
267 w: Pin<&mut W>,
268 ) -> impl Future<Output = Result<(), Error>> + Send;
269
270 fn reset(self: Pin<&mut Self>) -> impl Future<Output = bool> + Send;
274}
275
276trait AsyncWriteBodyEraser<W> {
278 fn write_body<'a>(
279 self: Pin<&'a mut Self>,
280 w: Pin<&'a mut W>,
281 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>;
282
283 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
284 where
285 W: 'a;
286}
287
288impl<T, W> AsyncWriteBodyEraser<W> for T
289where
290 T: AsyncWriteBody<W> + ?Sized,
291{
292 fn write_body<'a>(
293 self: Pin<&'a mut Self>,
294 w: Pin<&'a mut W>,
295 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>> {
296 Box::pin(self.write_body(w))
297 }
298
299 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + Send + 'a>>
300 where
301 W: 'a,
302 {
303 Box::pin(self.reset())
304 }
305}
306
307pub struct BoxAsyncWriteBody<'a, W> {
309 inner: Pin<Box<dyn AsyncWriteBodyEraser<W> + Send + 'a>>,
310}
311
312impl<'a, W> BoxAsyncWriteBody<'a, W> {
313 pub fn new<T>(v: T) -> Self
315 where
316 T: AsyncWriteBody<W> + Send + 'a,
317 {
318 BoxAsyncWriteBody { inner: Box::pin(v) }
319 }
320}
321
322impl<W> AsyncWriteBody<W> for BoxAsyncWriteBody<'_, W>
323where
324 W: Send,
325{
326 async fn write_body(mut self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error> {
327 self.inner.as_mut().write_body(w).await
328 }
329
330 async fn reset(mut self: Pin<&mut Self>) -> bool {
331 self.inner.as_mut().reset().await
332 }
333}
334
335pub trait LocalAsyncWriteBody<W> {
361 fn write_body(self: Pin<&mut Self>, w: Pin<&mut W>) -> impl Future<Output = Result<(), Error>>;
365
366 fn reset(self: Pin<&mut Self>) -> impl Future<Output = bool>;
370}
371
372trait LocalAsyncWriteBodyEraser<W> {
374 fn write_body<'a>(
375 self: Pin<&'a mut Self>,
376 w: Pin<&'a mut W>,
377 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>>;
378
379 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + 'a>>
380 where
381 W: 'a;
382}
383
384impl<T, W> LocalAsyncWriteBodyEraser<W> for T
385where
386 T: LocalAsyncWriteBody<W> + ?Sized,
387{
388 fn write_body<'a>(
389 self: Pin<&'a mut Self>,
390 w: Pin<&'a mut W>,
391 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>> {
392 Box::pin(self.write_body(w))
393 }
394
395 fn reset<'a>(self: Pin<&'a mut Self>) -> Pin<Box<dyn Future<Output = bool> + 'a>>
396 where
397 W: 'a,
398 {
399 Box::pin(self.reset())
400 }
401}
402
403pub struct BoxLocalAsyncWriteBody<'a, W> {
405 inner: Pin<Box<dyn LocalAsyncWriteBodyEraser<W> + 'a>>,
406}
407
408impl<'a, W> BoxLocalAsyncWriteBody<'a, W> {
409 pub fn new<T>(v: T) -> Self
411 where
412 T: LocalAsyncWriteBody<W> + 'a,
413 {
414 BoxLocalAsyncWriteBody { inner: Box::pin(v) }
415 }
416}
417
418impl<W> LocalAsyncWriteBody<W> for BoxLocalAsyncWriteBody<'_, W> {
419 async fn write_body(mut self: Pin<&mut Self>, w: Pin<&mut W>) -> Result<(), Error> {
420 self.inner.as_mut().write_body(w).await
421 }
422
423 async fn reset(mut self: Pin<&mut Self>) -> bool {
424 self.inner.as_mut().reset().await
425 }
426}
427
428pub trait SerializeRequest<'a, T, W> {
431 fn content_type(runtime: &ConjureRuntime, value: &T) -> HeaderValue;
433
434 fn content_length(runtime: &ConjureRuntime, value: &T) -> Option<u64> {
440 let _runtime = runtime;
441 let _value = value;
442 None
443 }
444
445 fn serialize(runtime: &ConjureRuntime, value: T) -> Result<RequestBody<'a, W>, Error>;
447}
448
449pub trait AsyncSerializeRequest<'a, T, W> {
452 fn content_type(runtime: &ConjureRuntime, value: &T) -> HeaderValue;
454
455 fn content_length(runtime: &ConjureRuntime, value: &T) -> Option<u64> {
461 let _runtime = runtime;
462 let _value = value;
463 None
464 }
465
466 fn serialize(runtime: &ConjureRuntime, value: T) -> Result<AsyncRequestBody<'a, W>, Error>;
468}
469
470pub trait LocalAsyncSerializeRequest<'a, T, W> {
473 fn content_type(runtime: &ConjureRuntime, value: &T) -> HeaderValue;
475
476 fn content_length(runtime: &ConjureRuntime, value: &T) -> Option<u64> {
482 let _runtime = runtime;
483 let _value = value;
484 None
485 }
486
487 fn serialize(runtime: &ConjureRuntime, value: T)
489 -> Result<LocalAsyncRequestBody<'a, W>, Error>;
490}
491
492pub enum StdRequestSerializer {}
494
495impl<'a, T, W> SerializeRequest<'a, T, W> for StdRequestSerializer
496where
497 T: Serialize,
498{
499 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
500 APPLICATION_JSON
501 }
502
503 fn serialize(_: &ConjureRuntime, value: T) -> Result<RequestBody<'a, W>, Error> {
504 let body = json::to_vec(&value).map_err(Error::internal)?;
505 Ok(RequestBody::Fixed(body.into()))
506 }
507}
508
509impl<'a, T, W> AsyncSerializeRequest<'a, T, W> for StdRequestSerializer
510where
511 T: Serialize,
512{
513 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
514 APPLICATION_JSON
515 }
516
517 fn serialize(_: &ConjureRuntime, value: T) -> Result<AsyncRequestBody<'a, W>, Error> {
518 let buf = json::to_vec(&value).map_err(Error::internal)?;
519 Ok(AsyncRequestBody::Fixed(Bytes::from(buf)))
520 }
521}
522
523impl<'a, T, W> LocalAsyncSerializeRequest<'a, T, W> for StdRequestSerializer
524where
525 T: Serialize,
526{
527 fn content_type(_: &ConjureRuntime, _: &T) -> HeaderValue {
528 APPLICATION_JSON
529 }
530
531 fn serialize(_: &ConjureRuntime, value: T) -> Result<LocalAsyncRequestBody<'a, W>, Error> {
532 let buf = json::to_vec(&value).map_err(Error::internal)?;
533 Ok(LocalAsyncRequestBody::Fixed(Bytes::from(buf)))
534 }
535}
536
537pub trait DeserializeResponse<T, R> {
540 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue>;
542
543 fn deserialize(runtime: &ConjureRuntime, response: Response<R>) -> Result<T, Error>;
545}
546
547pub trait AsyncDeserializeResponse<T, R> {
550 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue>;
552
553 fn deserialize(
555 runtime: &ConjureRuntime,
556 response: Response<R>,
557 ) -> impl Future<Output = Result<T, Error>> + Send;
558}
559
560pub trait LocalAsyncDeserializeResponse<T, R> {
563 fn accept(runtime: &ConjureRuntime) -> Option<HeaderValue>;
565
566 fn deserialize(
568 runtime: &ConjureRuntime,
569 response: Response<R>,
570 ) -> impl Future<Output = Result<T, Error>>;
571}
572
573pub enum UnitResponseDeserializer {}
575
576impl<R> DeserializeResponse<(), R> for UnitResponseDeserializer {
577 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
578 None
579 }
580
581 fn deserialize(_: &ConjureRuntime, _: Response<R>) -> Result<(), Error> {
582 Ok(())
583 }
584}
585
586impl<R> AsyncDeserializeResponse<(), R> for UnitResponseDeserializer
587where
588 R: Send,
589{
590 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
591 None
592 }
593
594 async fn deserialize(_: &ConjureRuntime, _: Response<R>) -> Result<(), Error> {
595 Ok(())
596 }
597}
598
599impl<R> LocalAsyncDeserializeResponse<(), R> for UnitResponseDeserializer {
600 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
601 None
602 }
603
604 async fn deserialize(_: &ConjureRuntime, _: Response<R>) -> Result<(), Error> {
605 Ok(())
606 }
607}
608
609pub enum StdResponseDeserializer {}
611
612impl<T, R> DeserializeResponse<T, R> for StdResponseDeserializer
613where
614 T: DeserializeOwned,
615 R: Iterator<Item = Result<Bytes, Error>>,
616{
617 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
618 Some(APPLICATION_JSON)
619 }
620
621 fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
622 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
623 return Err(Error::internal_safe("invalid response Content-Type"));
624 }
625 let buf = private::read_body(response.into_body(), None)?;
626 json::client_from_slice(&buf).map_err(Error::internal)
627 }
628}
629
630impl<T, R> AsyncDeserializeResponse<T, R> for StdResponseDeserializer
631where
632 T: DeserializeOwned,
633 R: Stream<Item = Result<Bytes, Error>> + Send,
634{
635 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
636 Some(APPLICATION_JSON)
637 }
638
639 async fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
640 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
641 return Err(Error::internal_safe("invalid response Content-Type"));
642 }
643 let buf = private::async_read_body(response.into_body(), None).await?;
644 json::client_from_slice(&buf).map_err(Error::internal)
645 }
646}
647
648impl<T, R> LocalAsyncDeserializeResponse<T, R> for StdResponseDeserializer
649where
650 T: DeserializeOwned,
651 R: Stream<Item = Result<Bytes, Error>>,
652{
653 fn accept(_: &ConjureRuntime) -> Option<HeaderValue> {
654 Some(APPLICATION_JSON)
655 }
656
657 async fn deserialize(_: &ConjureRuntime, response: Response<R>) -> Result<T, Error> {
658 if response.headers().get(CONTENT_TYPE) != Some(&APPLICATION_JSON) {
659 return Err(Error::internal_safe("invalid response Content-Type"));
660 }
661 let buf = private::async_read_body(response.into_body(), None).await?;
662 json::client_from_slice(&buf).map_err(Error::internal)
663 }
664}
665
666pub trait EncodeHeader<T> {
668 fn encode(runtime: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error>;
672}
673
674pub trait EncodeParam<T> {
677 fn encode(runtime: &ConjureRuntime, value: T) -> Result<Vec<String>, Error>;
683}
684
685pub enum DisplayEncoder {}
687
688impl<T> EncodeHeader<T> for DisplayEncoder
689where
690 T: Display,
691{
692 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error> {
693 HeaderValue::try_from(value.to_string())
694 .map_err(Error::internal_safe)
695 .map(|v| vec![v])
696 }
697}
698
699impl<T> EncodeParam<T> for DisplayEncoder
700where
701 T: Display,
702{
703 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<String>, Error> {
704 Ok(vec![value.to_string()])
705 }
706}
707
708pub enum DisplaySeqEncoder {}
711
712impl<T, U> EncodeHeader<T> for DisplaySeqEncoder
713where
714 T: IntoIterator<Item = U>,
715 U: Display,
716{
717 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error> {
718 value
719 .into_iter()
720 .map(|v| HeaderValue::try_from(v.to_string()).map_err(Error::internal_safe))
721 .collect()
722 }
723}
724
725impl<T, U> EncodeParam<T> for DisplaySeqEncoder
726where
727 T: IntoIterator<Item = U>,
728 U: Display,
729{
730 fn encode(_: &ConjureRuntime, value: T) -> Result<Vec<String>, Error> {
731 Ok(value.into_iter().map(|v| v.to_string()).collect())
732 }
733}
734
735pub struct AsRefEncoder<D, U> {
737 _p: PhantomData<(D, U)>,
738}
739
740impl<T, D, U> EncodeHeader<T> for AsRefEncoder<D, U>
741where
742 T: AsRef<U>,
743 for<'a> D: EncodeHeader<&'a U>,
744{
745 fn encode(runtime: &ConjureRuntime, value: T) -> Result<Vec<HeaderValue>, Error> {
746 D::encode(runtime, value.as_ref())
747 }
748}
749
750impl<T, D, U> EncodeParam<T> for AsRefEncoder<D, U>
751where
752 T: AsRef<U>,
753 for<'a> D: EncodeParam<&'a U>,
754{
755 fn encode(runtime: &ConjureRuntime, value: T) -> Result<Vec<String>, Error> {
756 D::encode(runtime, value.as_ref())
757 }
758}