cloud_sdk/authentication/
transport.rs1use core::fmt;
2use core::future::Future;
3
4use crate::transport::{
5 AsyncExecutionError, AsyncResponseStaging, RawResponsePolicy, ResponseCompletion,
6 ResponseWriter, TransportRequest,
7};
8
9use super::AuthenticationScopePolicy;
10
11#[derive(Clone, Copy)]
29pub struct AuthenticatedRequest<'request, 'policy> {
30 request: TransportRequest<'request>,
31 policy: AuthenticationScopePolicy<'policy>,
32 response_policy: RawResponsePolicy<'policy>,
33}
34
35impl<'request, 'policy> AuthenticatedRequest<'request, 'policy> {
36 #[must_use]
38 pub(crate) const fn new(
39 request: TransportRequest<'request>,
40 policy: AuthenticationScopePolicy<'policy>,
41 response_policy: &RawResponsePolicy<'policy>,
42 ) -> Self {
43 Self {
44 request,
45 policy,
46 response_policy: *response_policy,
47 }
48 }
49
50 #[must_use]
52 pub const fn transport_request(self) -> TransportRequest<'request> {
53 self.request
54 }
55
56 #[must_use]
58 pub const fn policy(self) -> AuthenticationScopePolicy<'policy> {
59 self.policy
60 }
61
62 #[must_use]
64 pub const fn response_policy(self) -> RawResponsePolicy<'policy> {
65 self.response_policy
66 }
67}
68
69impl fmt::Debug for AuthenticatedRequest<'_, '_> {
70 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
71 formatter
72 .debug_struct("AuthenticatedRequest")
73 .field("request", &self.request)
74 .field("policy", &self.policy)
75 .field("response_policy", &self.response_policy)
76 .finish()
77 }
78}
79
80pub trait BlockingAuthenticatedTransport {
82 type Error;
84
85 fn send_authenticated(
87 &self,
88 request: AuthenticatedRequest<'_, '_>,
89 response: &mut ResponseWriter<'_>,
90 ) -> Result<(), Self::Error>;
91}
92
93pub trait AsyncAuthenticatedTransport {
98 type Error;
100
101 fn send_authenticated<'transport, 'request, 'policy, 'writer, 'buffer>(
103 &'transport self,
104 request: AuthenticatedRequest<'request, 'policy>,
105 response: AsyncResponseStaging<'writer, 'buffer>,
106 ) -> impl Future<Output = Result<ResponseCompletion, Self::Error>> + Send + 'writer
107 where
108 'transport: 'writer,
109 'request: 'writer,
110 'policy: 'writer,
111 'buffer: 'writer;
112}
113
114pub trait LocalAsyncAuthenticatedTransport {
121 type Error;
123
124 fn send_authenticated_local<'transport, 'request, 'policy, 'writer, 'buffer>(
126 &'transport self,
127 request: AuthenticatedRequest<'request, 'policy>,
128 response: AsyncResponseStaging<'writer, 'buffer>,
129 ) -> impl Future<Output = Result<ResponseCompletion, Self::Error>> + 'writer
130 where
131 'transport: 'writer,
132 'request: 'writer,
133 'policy: 'writer,
134 'buffer: 'writer;
135}
136
137pub async fn drive_local_authenticated<'transport, 'request, 'policy, 'writer, 'buffer, T>(
139 transport: &'transport T,
140 request: AuthenticatedRequest<'request, 'policy>,
141 response: &'writer mut ResponseWriter<'buffer>,
142) -> Result<(), AsyncExecutionError<T::Error>>
143where
144 T: LocalAsyncAuthenticatedTransport + ?Sized,
145 'transport: 'writer,
146 'request: 'writer,
147 'policy: 'writer,
148 'buffer: 'writer,
149{
150 let mut attempt = response
151 .begin_attempt()
152 .map_err(AsyncExecutionError::Response)?;
153 let completion = transport
154 .send_authenticated_local(request, attempt.staging())
155 .await
156 .map_err(AsyncExecutionError::Transport)?;
157 attempt
158 .commit_completion(completion)
159 .map_err(AsyncExecutionError::Response)
160}
161
162pub async fn drive_async_authenticated<'transport, 'request, 'policy, 'writer, 'buffer, T>(
164 transport: &'transport T,
165 request: AuthenticatedRequest<'request, 'policy>,
166 response: &'writer mut ResponseWriter<'buffer>,
167) -> Result<(), AsyncExecutionError<T::Error>>
168where
169 T: AsyncAuthenticatedTransport + ?Sized,
170 'transport: 'writer,
171 'request: 'writer,
172 'policy: 'writer,
173 'buffer: 'writer,
174{
175 let mut attempt = response
176 .begin_attempt()
177 .map_err(AsyncExecutionError::Response)?;
178 let completion = transport
179 .send_authenticated(request, attempt.staging())
180 .await
181 .map_err(AsyncExecutionError::Transport)?;
182 attempt
183 .commit_completion(completion)
184 .map_err(AsyncExecutionError::Response)
185}
186
187impl<T> LocalAsyncAuthenticatedTransport for T
188where
189 T: AsyncAuthenticatedTransport + ?Sized,
190{
191 type Error = T::Error;
192
193 async fn send_authenticated_local<'transport, 'request, 'policy, 'writer, 'buffer>(
194 &'transport self,
195 request: AuthenticatedRequest<'request, 'policy>,
196 response: AsyncResponseStaging<'writer, 'buffer>,
197 ) -> Result<ResponseCompletion, Self::Error>
198 where
199 'transport: 'writer,
200 'request: 'writer,
201 'policy: 'writer,
202 'buffer: 'writer,
203 {
204 AsyncAuthenticatedTransport::send_authenticated(self, request, response).await
205 }
206}