1use bytes::Bytes;
17use conjure_error::{Error, InvalidArgument};
18use futures_core::Stream;
19use http::header::CONTENT_TYPE;
20use http::{
21 request, Extensions, HeaderMap, HeaderValue, Method, Request, Response, StatusCode, Uri,
22};
23use serde::de::DeserializeOwned;
24use serde::Serialize;
25use std::borrow::Cow;
26use std::error;
27use std::future::Future;
28use std::io::Write;
29use std::iter::FromIterator;
30use std::marker::PhantomData;
31use std::pin::Pin;
32use std::str;
33use std::str::FromStr;
34use std::sync::Arc;
35
36use crate::private::{self, SERIALIZABLE_REQUEST_SIZE_LIMIT};
37pub use crate::server::encoding::*;
38#[doc(inline)]
39pub use crate::server::runtime::ConjureRuntime;
40
41pub mod conjure;
42mod encoding;
43pub mod runtime;
44
45pub trait EndpointMetadata {
47 fn method(&self) -> Method;
49
50 fn path(&self) -> &[PathSegment];
54
55 fn template(&self) -> &str;
59
60 fn service_name(&self) -> &str;
62
63 fn name(&self) -> &str;
65
66 fn deprecated(&self) -> Option<&str>;
68}
69
70impl<T> EndpointMetadata for Box<T>
71where
72 T: ?Sized + EndpointMetadata,
73{
74 fn method(&self) -> Method {
75 (**self).method()
76 }
77
78 fn path(&self) -> &[PathSegment] {
79 (**self).path()
80 }
81
82 fn template(&self) -> &str {
83 (**self).template()
84 }
85
86 fn service_name(&self) -> &str {
87 (**self).service_name()
88 }
89
90 fn name(&self) -> &str {
91 (**self).name()
92 }
93
94 fn deprecated(&self) -> Option<&str> {
95 (**self).deprecated()
96 }
97}
98
99pub trait Endpoint<I, O>: EndpointMetadata {
101 fn handle(
111 &self,
112 req: Request<I>,
113 response_extensions: &mut Extensions,
114 ) -> Result<Response<ResponseBody<O>>, Error>;
115}
116
117impl<T, I, O> Endpoint<I, O> for Box<T>
118where
119 T: ?Sized + Endpoint<I, O>,
120{
121 fn handle(
122 &self,
123 req: Request<I>,
124 response_extensions: &mut Extensions,
125 ) -> Result<Response<ResponseBody<O>>, Error> {
126 (**self).handle(req, response_extensions)
127 }
128}
129
130pub trait AsyncEndpoint<I, O>: EndpointMetadata {
132 fn handle(
142 &self,
143 req: Request<I>,
144 response_extensions: &mut Extensions,
145 ) -> impl Future<Output = Result<Response<AsyncResponseBody<O>>, Error>> + Send;
146}
147
148impl<T, I, O> AsyncEndpoint<I, O> for Box<T>
149where
150 T: ?Sized + AsyncEndpoint<I, O>,
151{
152 fn handle(
153 &self,
154 req: Request<I>,
155 response_extensions: &mut Extensions,
156 ) -> impl Future<Output = Result<Response<AsyncResponseBody<O>>, Error>> + Send {
157 (**self).handle(req, response_extensions)
158 }
159}
160
161trait AsyncEndpointEraser<I, O>: EndpointMetadata {
163 #[allow(clippy::type_complexity)]
164 fn handle<'a>(
165 &'a self,
166 req: Request<I>,
167 response_extensions: &'a mut Extensions,
168 ) -> Pin<Box<dyn Future<Output = Result<Response<AsyncResponseBody<O>>, Error>> + Send + 'a>>
169 where
170 I: 'a,
171 O: 'a;
172}
173
174impl<T, I, O> AsyncEndpointEraser<I, O> for T
175where
176 T: AsyncEndpoint<I, O>,
177{
178 fn handle<'a>(
179 &'a self,
180 req: Request<I>,
181 response_extensions: &'a mut Extensions,
182 ) -> Pin<Box<dyn Future<Output = Result<Response<AsyncResponseBody<O>>, Error>> + Send + 'a>>
183 where
184 I: 'a,
185 O: 'a,
186 {
187 Box::pin(self.handle(req, response_extensions))
188 }
189}
190
191pub struct BoxAsyncEndpoint<'a, I, O> {
193 inner: Box<dyn AsyncEndpointEraser<I, O> + 'a + Sync + Send>,
194}
195
196impl<'a, I, O> BoxAsyncEndpoint<'a, I, O> {
197 pub fn new<T>(v: T) -> Self
199 where
200 T: AsyncEndpoint<I, O> + Sync + Send + 'a,
201 {
202 BoxAsyncEndpoint { inner: Box::new(v) }
203 }
204}
205
206impl<I, O> EndpointMetadata for BoxAsyncEndpoint<'_, I, O> {
207 fn method(&self) -> Method {
208 self.inner.method()
209 }
210
211 fn path(&self) -> &[PathSegment] {
212 self.inner.path()
213 }
214
215 fn template(&self) -> &str {
216 self.inner.template()
217 }
218
219 fn service_name(&self) -> &str {
220 self.inner.service_name()
221 }
222
223 fn name(&self) -> &str {
224 self.inner.name()
225 }
226
227 fn deprecated(&self) -> Option<&str> {
228 self.inner.deprecated()
229 }
230}
231
232impl<I, O> AsyncEndpoint<I, O> for BoxAsyncEndpoint<'_, I, O>
233where
234 I: Send,
235{
236 async fn handle(
237 &self,
238 req: Request<I>,
239 response_extensions: &mut Extensions,
240 ) -> Result<Response<AsyncResponseBody<O>>, Error> {
241 self.inner.handle(req, response_extensions).await
242 }
243}
244
245pub trait LocalAsyncEndpoint<I, O>: EndpointMetadata {
247 fn handle(
257 &self,
258 req: Request<I>,
259 response_extensions: &mut Extensions,
260 ) -> impl Future<Output = Result<Response<LocalAsyncResponseBody<O>>, Error>>;
261}
262
263impl<T, I, O> LocalAsyncEndpoint<I, O> for Box<T>
264where
265 T: ?Sized + LocalAsyncEndpoint<I, O>,
266{
267 fn handle(
268 &self,
269 req: Request<I>,
270 response_extensions: &mut Extensions,
271 ) -> impl Future<Output = Result<Response<LocalAsyncResponseBody<O>>, Error>> {
272 (**self).handle(req, response_extensions)
273 }
274}
275
276trait LocalAsyncEndpointEraser<I, O>: EndpointMetadata {
278 #[allow(clippy::type_complexity)]
279 fn handle<'a>(
280 &'a self,
281 req: Request<I>,
282 response_extensions: &'a mut Extensions,
283 ) -> Pin<Box<dyn Future<Output = Result<Response<LocalAsyncResponseBody<O>>, Error>> + 'a>>
284 where
285 I: 'a,
286 O: 'a;
287}
288
289impl<T, I, O> LocalAsyncEndpointEraser<I, O> for T
290where
291 T: LocalAsyncEndpoint<I, O>,
292{
293 fn handle<'a>(
294 &'a self,
295 req: Request<I>,
296 response_extensions: &'a mut Extensions,
297 ) -> Pin<Box<dyn Future<Output = Result<Response<LocalAsyncResponseBody<O>>, Error>> + 'a>>
298 where
299 I: 'a,
300 O: 'a,
301 {
302 Box::pin(self.handle(req, response_extensions))
303 }
304}
305
306pub struct BoxLocalAsyncEndpoint<'a, I, O> {
308 inner: Box<dyn LocalAsyncEndpointEraser<I, O> + 'a>,
309}
310
311impl<'a, I, O> BoxLocalAsyncEndpoint<'a, I, O> {
312 pub fn new<T>(v: T) -> Self
314 where
315 T: LocalAsyncEndpoint<I, O> + 'a,
316 {
317 BoxLocalAsyncEndpoint { inner: Box::new(v) }
318 }
319}
320
321impl<I, O> EndpointMetadata for BoxLocalAsyncEndpoint<'_, I, O> {
322 fn method(&self) -> Method {
323 self.inner.method()
324 }
325
326 fn path(&self) -> &[PathSegment] {
327 self.inner.path()
328 }
329
330 fn template(&self) -> &str {
331 self.inner.template()
332 }
333
334 fn service_name(&self) -> &str {
335 self.inner.service_name()
336 }
337
338 fn name(&self) -> &str {
339 self.inner.name()
340 }
341
342 fn deprecated(&self) -> Option<&str> {
343 self.inner.deprecated()
344 }
345}
346
347impl<I, O> LocalAsyncEndpoint<I, O> for BoxLocalAsyncEndpoint<'_, I, O> {
348 async fn handle(
349 &self,
350 req: Request<I>,
351 response_extensions: &mut Extensions,
352 ) -> Result<Response<LocalAsyncResponseBody<O>>, Error> {
353 self.inner.handle(req, response_extensions).await
354 }
355}
356
357#[derive(Debug, Clone)]
359pub enum PathSegment {
360 Literal(Cow<'static, str>),
362
363 Parameter {
365 name: Cow<'static, str>,
367
368 regex: Option<Cow<'static, str>>,
370 },
371}
372
373pub enum ResponseBody<O> {
375 Empty,
377 Fixed(Bytes),
379 Streaming(Box<dyn WriteBody<O>>),
381}
382
383pub enum AsyncResponseBody<O> {
385 Empty,
387 Fixed(Bytes),
389 Streaming(BoxAsyncWriteBody<'static, O>),
391}
392
393pub enum LocalAsyncResponseBody<O> {
395 Empty,
397 Fixed(Bytes),
399 Streaming(BoxLocalAsyncWriteBody<'static, O>),
401}
402
403pub trait Service<I, O> {
405 fn endpoints(
407 &self,
408 runtime: &Arc<ConjureRuntime>,
409 ) -> Vec<Box<dyn Endpoint<I, O> + Sync + Send>>;
410}
411
412pub trait AsyncService<I, O> {
414 fn endpoints(&self, runtime: &Arc<ConjureRuntime>) -> Vec<BoxAsyncEndpoint<'static, I, O>>;
416}
417
418pub trait LocalAsyncService<I, O> {
420 fn endpoints(&self, runtime: &Arc<ConjureRuntime>)
422 -> Vec<BoxLocalAsyncEndpoint<'static, I, O>>;
423}
424
425pub trait WriteBody<W> {
427 fn write_body(self: Box<Self>, w: &mut W) -> Result<(), Error>;
430}
431
432impl<W> WriteBody<W> for Vec<u8>
433where
434 W: Write,
435{
436 fn write_body(self: Box<Self>, w: &mut W) -> Result<(), Error> {
437 w.write_all(&self).map_err(Error::internal_safe)
438 }
439}
440
441pub trait AsyncWriteBody<W> {
463 fn write_body(self, w: Pin<&mut W>) -> impl Future<Output = Result<(), Error>> + Send;
465}
466
467trait AsyncWriteBodyEraser<W> {
469 fn write_body<'a>(
470 self: Box<Self>,
471 w: Pin<&'a mut W>,
472 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>
473 where
474 Self: 'a;
475}
476
477impl<T, W> AsyncWriteBodyEraser<W> for T
478where
479 T: AsyncWriteBody<W>,
480{
481 fn write_body<'a>(
482 self: Box<Self>,
483 w: Pin<&'a mut W>,
484 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'a>>
485 where
486 Self: 'a,
487 {
488 Box::pin((*self).write_body(w))
489 }
490}
491
492pub struct BoxAsyncWriteBody<'a, W> {
494 inner: Box<dyn AsyncWriteBodyEraser<W> + Send + 'a>,
495}
496
497impl<'a, W> BoxAsyncWriteBody<'a, W> {
498 pub fn new<T>(v: T) -> Self
500 where
501 T: AsyncWriteBody<W> + Send + 'a,
502 {
503 BoxAsyncWriteBody { inner: Box::new(v) }
504 }
505}
506
507impl<W> AsyncWriteBody<W> for BoxAsyncWriteBody<'_, W>
508where
509 W: Send,
510{
511 async fn write_body(self, w: Pin<&mut W>) -> Result<(), Error>
512 where
513 W: Send,
514 {
515 self.inner.write_body(w).await
516 }
517}
518
519pub trait LocalAsyncWriteBody<W> {
541 fn write_body(self, w: Pin<&mut W>) -> impl Future<Output = Result<(), Error>>;
543}
544
545trait LocalAsyncWriteBodyEraser<W> {
547 fn write_body<'a>(
548 self: Box<Self>,
549 w: Pin<&'a mut W>,
550 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>>
551 where
552 Self: 'a;
553}
554
555impl<T, W> LocalAsyncWriteBodyEraser<W> for T
556where
557 T: LocalAsyncWriteBody<W>,
558{
559 fn write_body<'a>(
560 self: Box<Self>,
561 w: Pin<&'a mut W>,
562 ) -> Pin<Box<dyn Future<Output = Result<(), Error>> + 'a>>
563 where
564 Self: 'a,
565 {
566 Box::pin((*self).write_body(w))
567 }
568}
569
570pub struct BoxLocalAsyncWriteBody<'a, W> {
572 inner: Box<dyn LocalAsyncWriteBodyEraser<W> + 'a>,
573}
574
575impl<'a, W> BoxLocalAsyncWriteBody<'a, W> {
576 pub fn new<T>(v: T) -> Self
578 where
579 T: LocalAsyncWriteBody<W> + 'a,
580 {
581 BoxLocalAsyncWriteBody { inner: Box::new(v) }
582 }
583}
584
585impl<W> LocalAsyncWriteBody<W> for BoxLocalAsyncWriteBody<'_, W> {
586 async fn write_body(self, w: Pin<&mut W>) -> Result<(), Error> {
587 self.inner.write_body(w).await
588 }
589}
590
591pub struct RequestContext<'a> {
596 request_parts: &'a request::Parts,
597 response_extensions: &'a mut Extensions,
598}
599
600impl<'a> RequestContext<'a> {
601 #[doc(hidden)]
602 #[inline]
603 pub fn new(request_parts: &'a request::Parts, response_extensions: &'a mut Extensions) -> Self {
604 RequestContext {
605 request_parts,
606 response_extensions,
607 }
608 }
609
610 #[inline]
612 pub fn request_uri(&self) -> &Uri {
613 &self.request_parts.uri
614 }
615
616 #[inline]
618 pub fn request_headers(&self) -> &HeaderMap {
619 &self.request_parts.headers
620 }
621
622 #[inline]
624 pub fn request_extensions(&self) -> &Extensions {
625 &self.request_parts.extensions
626 }
627
628 #[inline]
630 pub fn response_extensions(&self) -> &Extensions {
631 self.response_extensions
632 }
633
634 #[inline]
636 pub fn response_extensions_mut(&mut self) -> &mut Extensions {
637 self.response_extensions
638 }
639}
640
641#[derive(Copy, Clone, Debug)]
647pub struct UseLegacyErrorSerialization;
648
649pub trait DeserializeRequest<T, R> {
652 fn deserialize(runtime: &ConjureRuntime, headers: &HeaderMap, body: R) -> Result<T, Error>;
654}
655
656pub trait AsyncDeserializeRequest<T, R> {
659 fn deserialize(
661 runtime: &ConjureRuntime,
662 headers: &HeaderMap,
663 body: R,
664 ) -> impl Future<Output = Result<T, Error>> + Send;
665}
666
667pub trait LocalAsyncDeserializeRequest<T, R> {
670 fn deserialize(
672 runtime: &ConjureRuntime,
673 headers: &HeaderMap,
674 body: R,
675 ) -> impl Future<Output = Result<T, Error>>;
676}
677
678pub enum StdRequestDeserializer<const N: usize = { SERIALIZABLE_REQUEST_SIZE_LIMIT }> {}
683
684impl<const N: usize> StdRequestDeserializer<N> {
685 async fn deserialize_inner<T, R>(
686 runtime: &ConjureRuntime,
687 headers: &HeaderMap,
688 body: R,
689 ) -> Result<T, Error>
690 where
691 T: DeserializeOwned,
692 R: Stream<Item = Result<Bytes, Error>>,
693 {
694 let encoding = runtime.request_body_encoding(headers)?;
695 let buf = private::async_read_body(body, Some(N)).await?;
696 let v = T::deserialize(encoding.deserializer(&buf).deserializer())
697 .map_err(|e| Error::service(e, InvalidArgument::new()))?;
698 Ok(v)
699 }
700}
701
702impl<const N: usize, T, R> DeserializeRequest<T, R> for StdRequestDeserializer<N>
703where
704 T: DeserializeOwned,
705 R: Iterator<Item = Result<Bytes, Error>>,
706{
707 fn deserialize(runtime: &ConjureRuntime, headers: &HeaderMap, body: R) -> Result<T, Error> {
708 let encoding = runtime.request_body_encoding(headers)?;
709 let buf = private::read_body(body, Some(N))?;
710 let v = T::deserialize(encoding.deserializer(&buf).deserializer())
711 .map_err(|e| Error::service(e, InvalidArgument::new()))?;
712 Ok(v)
713 }
714}
715
716impl<const N: usize, T, R> AsyncDeserializeRequest<T, R> for StdRequestDeserializer<N>
717where
718 T: DeserializeOwned,
719 R: Stream<Item = Result<Bytes, Error>> + Send,
720{
721 async fn deserialize(
722 runtime: &ConjureRuntime,
723 headers: &HeaderMap,
724 body: R,
725 ) -> Result<T, Error> {
726 Self::deserialize_inner(runtime, headers, body).await
727 }
728}
729
730impl<const N: usize, T, R> LocalAsyncDeserializeRequest<T, R> for StdRequestDeserializer<N>
731where
732 T: DeserializeOwned,
733 R: Stream<Item = Result<Bytes, Error>>,
734{
735 async fn deserialize(
736 runtime: &ConjureRuntime,
737 headers: &HeaderMap,
738 body: R,
739 ) -> Result<T, Error> {
740 Self::deserialize_inner(runtime, headers, body).await
741 }
742}
743
744pub struct FromRequestDeserializer<D, U> {
746 _p: PhantomData<(D, U)>,
747}
748
749impl<T, R, D, U> DeserializeRequest<T, R> for FromRequestDeserializer<D, U>
750where
751 T: From<U>,
752 D: DeserializeRequest<U, R>,
753{
754 fn deserialize(runtime: &ConjureRuntime, headers: &HeaderMap, body: R) -> Result<T, Error> {
755 D::deserialize(runtime, headers, body).map(From::from)
756 }
757}
758
759impl<T, R, D, U> AsyncDeserializeRequest<T, R> for FromRequestDeserializer<D, U>
760where
761 T: From<U>,
762 D: AsyncDeserializeRequest<U, R>,
763 R: Send,
764{
765 async fn deserialize(
766 runtime: &ConjureRuntime,
767 headers: &HeaderMap,
768 body: R,
769 ) -> Result<T, Error> {
770 D::deserialize(runtime, headers, body).await.map(From::from)
771 }
772}
773
774impl<T, R, D, U> LocalAsyncDeserializeRequest<T, R> for FromRequestDeserializer<D, U>
775where
776 T: From<U>,
777 D: LocalAsyncDeserializeRequest<U, R>,
778{
779 async fn deserialize(
780 runtime: &ConjureRuntime,
781 headers: &HeaderMap,
782 body: R,
783 ) -> Result<T, Error> {
784 D::deserialize(runtime, headers, body).await.map(From::from)
785 }
786}
787
788pub trait SerializeResponse<T, W> {
790 fn serialize(
792 runtime: &ConjureRuntime,
793 request_headers: &HeaderMap,
794 value: T,
795 ) -> Result<Response<ResponseBody<W>>, Error>;
796}
797
798pub trait AsyncSerializeResponse<T, W> {
801 fn serialize(
803 runtime: &ConjureRuntime,
804 request_headers: &HeaderMap,
805 value: T,
806 ) -> Result<Response<AsyncResponseBody<W>>, Error>;
807}
808
809pub trait LocalAsyncSerializeResponse<T, W> {
812 fn serialize(
814 runtime: &ConjureRuntime,
815 request_headers: &HeaderMap,
816 value: T,
817 ) -> Result<Response<LocalAsyncResponseBody<W>>, Error>;
818}
819
820pub enum EmptyResponseSerializer {}
822
823impl EmptyResponseSerializer {
824 fn serialize_inner<T>(body: T) -> Result<Response<T>, Error> {
825 let mut response = Response::new(body);
826 *response.status_mut() = StatusCode::NO_CONTENT;
827 Ok(response)
828 }
829}
830
831impl<W> SerializeResponse<(), W> for EmptyResponseSerializer {
832 fn serialize(
833 _: &ConjureRuntime,
834 _: &HeaderMap,
835 _: (),
836 ) -> Result<Response<ResponseBody<W>>, Error> {
837 Self::serialize_inner(ResponseBody::Empty)
838 }
839}
840
841impl<W> AsyncSerializeResponse<(), W> for EmptyResponseSerializer {
842 fn serialize(
843 _: &ConjureRuntime,
844 _: &HeaderMap,
845 _: (),
846 ) -> Result<Response<AsyncResponseBody<W>>, Error> {
847 Self::serialize_inner(AsyncResponseBody::Empty)
848 }
849}
850
851impl<W> LocalAsyncSerializeResponse<(), W> for EmptyResponseSerializer {
852 fn serialize(
853 _: &ConjureRuntime,
854 _: &HeaderMap,
855 _: (),
856 ) -> Result<Response<LocalAsyncResponseBody<W>>, Error> {
857 Self::serialize_inner(LocalAsyncResponseBody::Empty)
858 }
859}
860
861pub enum StdResponseSerializer {}
863
864impl StdResponseSerializer {
865 fn serialize_inner<B>(
866 runtime: &ConjureRuntime,
867 request_headers: &HeaderMap,
868 value: &dyn erased_serde::Serialize,
869 make_body: impl FnOnce(Bytes) -> B,
870 ) -> Result<Response<B>, Error> {
871 let encoding = runtime.response_body_encoding(request_headers)?;
872
873 let mut body = vec![];
874 value
875 .erased_serialize(&mut *encoding.serializer(&mut body).serializer())
876 .map_err(Error::internal)?;
877
878 let mut response = Response::new(make_body(body.into()));
879 response
880 .headers_mut()
881 .insert(CONTENT_TYPE, encoding.content_type());
882
883 Ok(response)
884 }
885}
886
887impl<T, W> SerializeResponse<T, W> for StdResponseSerializer
888where
889 T: Serialize,
890{
891 fn serialize(
892 runtime: &ConjureRuntime,
893 request_headers: &HeaderMap,
894 value: T,
895 ) -> Result<Response<ResponseBody<W>>, Error> {
896 Self::serialize_inner(runtime, request_headers, &value, ResponseBody::Fixed)
897 }
898}
899
900impl<T, W> AsyncSerializeResponse<T, W> for StdResponseSerializer
901where
902 T: Serialize,
903{
904 fn serialize(
905 runtime: &ConjureRuntime,
906 request_headers: &HeaderMap,
907 value: T,
908 ) -> Result<Response<AsyncResponseBody<W>>, Error> {
909 Self::serialize_inner(runtime, request_headers, &value, AsyncResponseBody::Fixed)
910 }
911}
912
913impl<T, W> LocalAsyncSerializeResponse<T, W> for StdResponseSerializer
914where
915 T: Serialize,
916{
917 fn serialize(
918 runtime: &ConjureRuntime,
919 request_headers: &HeaderMap,
920 value: T,
921 ) -> Result<Response<LocalAsyncResponseBody<W>>, Error> {
922 Self::serialize_inner(
923 runtime,
924 request_headers,
925 &value,
926 LocalAsyncResponseBody::Fixed,
927 )
928 }
929}
930
931pub trait DecodeHeader<T> {
933 fn decode<'a, I>(runtime: &ConjureRuntime, headers: I) -> Result<T, Error>
935 where
936 I: IntoIterator<Item = &'a HeaderValue>;
937}
938
939pub trait DecodeParam<T> {
942 fn decode<I>(runtime: &ConjureRuntime, params: I) -> Result<T, Error>
946 where
947 I: IntoIterator,
948 I::Item: AsRef<str>;
949}
950
951pub enum FromStrDecoder {}
953
954impl<T> DecodeHeader<T> for FromStrDecoder
955where
956 T: FromStr,
957 T::Err: Into<Box<dyn error::Error + Sync + Send>>,
958{
959 fn decode<'a, I>(_: &ConjureRuntime, headers: I) -> Result<T, Error>
960 where
961 I: IntoIterator<Item = &'a HeaderValue>,
962 {
963 only_item(headers)?
964 .to_str()
965 .map_err(|e| Error::service(e, InvalidArgument::new()))?
966 .parse()
967 .map_err(|e| Error::service(e, InvalidArgument::new()))
968 }
969}
970
971impl<T> DecodeParam<T> for FromStrDecoder
972where
973 T: FromStr,
974 T::Err: Into<Box<dyn error::Error + Sync + Send>>,
975{
976 fn decode<I>(_: &ConjureRuntime, params: I) -> Result<T, Error>
977 where
978 I: IntoIterator,
979 I::Item: AsRef<str>,
980 {
981 only_item(params)?
982 .as_ref()
983 .parse()
984 .map_err(|e| Error::service(e, InvalidArgument::new()))
985 }
986}
987
988pub enum FromStrOptionDecoder {}
990
991impl<T> DecodeHeader<Option<T>> for FromStrOptionDecoder
992where
993 T: FromStr,
994 T::Err: Into<Box<dyn error::Error + Sync + Send>>,
995{
996 fn decode<'a, I>(_: &ConjureRuntime, headers: I) -> Result<Option<T>, Error>
997 where
998 I: IntoIterator<Item = &'a HeaderValue>,
999 {
1000 let Some(header) = optional_item(headers)? else {
1001 return Ok(None);
1002 };
1003 let value = header
1004 .to_str()
1005 .map_err(|e| Error::service(e, InvalidArgument::new()))?
1006 .parse()
1007 .map_err(|e| Error::service(e, InvalidArgument::new()))?;
1008 Ok(Some(value))
1009 }
1010}
1011
1012impl<T> DecodeParam<Option<T>> for FromStrOptionDecoder
1013where
1014 T: FromStr,
1015 T::Err: Into<Box<dyn error::Error + Sync + Send>>,
1016{
1017 fn decode<I>(_: &ConjureRuntime, params: I) -> Result<Option<T>, Error>
1018 where
1019 I: IntoIterator,
1020 I::Item: AsRef<str>,
1021 {
1022 let Some(param) = optional_item(params)? else {
1023 return Ok(None);
1024 };
1025 let value = param
1026 .as_ref()
1027 .parse()
1028 .map_err(|e| Error::service(e, InvalidArgument::new()))?;
1029 Ok(Some(value))
1030 }
1031}
1032
1033fn optional_item<I>(it: I) -> Result<Option<I::Item>, Error>
1034where
1035 I: IntoIterator,
1036{
1037 let mut it = it.into_iter();
1038 let Some(item) = it.next() else {
1039 return Ok(None);
1040 };
1041
1042 let remaining = it.count();
1043 if remaining > 0 {
1044 return Err(
1045 Error::service_safe("expected at most 1 parameter", InvalidArgument::new())
1046 .with_safe_param("actual", remaining + 1),
1047 );
1048 }
1049
1050 Ok(Some(item))
1051}
1052
1053pub struct FromStrSeqDecoder<U> {
1056 _p: PhantomData<U>,
1057}
1058
1059impl<T, U> DecodeParam<T> for FromStrSeqDecoder<U>
1060where
1061 T: FromIterator<U>,
1062 U: FromStr,
1063 U::Err: Into<Box<dyn error::Error + Sync + Send>>,
1064{
1065 fn decode<I>(_: &ConjureRuntime, params: I) -> Result<T, Error>
1066 where
1067 I: IntoIterator,
1068 I::Item: AsRef<str>,
1069 {
1070 params
1071 .into_iter()
1072 .map(|s| {
1073 s.as_ref()
1074 .parse()
1075 .map_err(|e| Error::service(e, InvalidArgument::new()))
1076 })
1077 .collect()
1078 }
1079}
1080
1081fn only_item<I>(it: I) -> Result<I::Item, Error>
1082where
1083 I: IntoIterator,
1084{
1085 let mut it = it.into_iter();
1086 let Some(item) = it.next() else {
1087 return Err(
1088 Error::service_safe("expected exactly 1 parameter", InvalidArgument::new())
1089 .with_safe_param("actual", 0),
1090 );
1091 };
1092
1093 let remaining = it.count();
1094 if remaining > 0 {
1095 return Err(
1096 Error::service_safe("expected exactly 1 parameter", InvalidArgument::new())
1097 .with_safe_param("actual", remaining + 1),
1098 );
1099 }
1100
1101 Ok(item)
1102}
1103
1104pub struct FromDecoder<D, U> {
1106 _p: PhantomData<(D, U)>,
1107}
1108
1109impl<T, D, U> DecodeParam<T> for FromDecoder<D, U>
1110where
1111 T: From<U>,
1112 D: DecodeParam<U>,
1113{
1114 fn decode<I>(runtime: &ConjureRuntime, params: I) -> Result<T, Error>
1115 where
1116 I: IntoIterator,
1117 I::Item: AsRef<str>,
1118 {
1119 D::decode(runtime, params).map(T::from)
1120 }
1121}
1122
1123impl<T, D, U> DecodeHeader<T> for FromDecoder<D, U>
1124where
1125 T: From<U>,
1126 D: DecodeHeader<U>,
1127{
1128 fn decode<'a, I>(runtime: &ConjureRuntime, headers: I) -> Result<T, Error>
1129 where
1130 I: IntoIterator<Item = &'a HeaderValue>,
1131 {
1132 D::decode(runtime, headers).map(T::from)
1133 }
1134}