1use crate::{ApiComponent, PathItemDefinition};
2use actix_web::{HttpRequest, HttpResponse, Responder};
3use apistos_models::Schema;
4use apistos_models::components::Components;
5use apistos_models::paths::Operation;
6use apistos_models::reference_or::ReferenceOr;
7use pin_project::pin_project;
8use std::future::Future;
9use std::pin::Pin;
10use std::task::{Context, Poll};
11
12#[pin_project]
13pub struct ResponseWrapper<R, P> {
14 #[pin]
15 pub inner: R,
16 pub path_item: P,
17}
18
19impl<R: Responder, P> Responder for ResponseWrapper<R, P> {
20 type Body = R::Body;
21
22 fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
23 self.inner.respond_to(req)
24 }
25}
26
27impl<F, R, P> Future for ResponseWrapper<F, P>
28where
29 F: Future<Output = R>,
30 R: Responder,
31 P: PathItemDefinition,
32{
33 type Output = R;
34
35 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36 self.as_mut().project().inner.poll(cx)
37 }
38}
39
40impl<F, R, P> PathItemDefinition for ResponseWrapper<F, P>
41where
42 F: Future<Output = R>,
43 R: Responder,
44 P: PathItemDefinition,
45{
46 fn is_visible() -> bool {
47 P::is_visible()
48 }
49
50 fn operation() -> Operation {
51 P::operation()
52 }
53
54 fn components() -> Vec<Components> {
55 P::components()
56 }
57}
58
59pub struct ResponderWrapper<T>(pub T);
60
61impl<T: Responder> ApiComponent for ResponderWrapper<T> {
62 fn child_schemas() -> Vec<(String, ReferenceOr<Schema>)> {
63 vec![]
64 }
65
66 fn schema() -> Option<(String, ReferenceOr<Schema>)> {
67 None
68 }
69}
70
71impl<T: Responder> PathItemDefinition for ResponderWrapper<T> {}
72
73impl<T: Responder> Responder for ResponderWrapper<T> {
74 type Body = T::Body;
75
76 fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
77 self.0.respond_to(req)
78 }
79}