1use super::{ClientExecutionError, ClientKernel, ClientResponse, ClientWorkspaceLease};
2use crate::authentication::{
3 AsyncAuthenticatedTransport, BlockingAuthenticatedTransport, LocalAsyncAuthenticatedTransport,
4};
5use crate::operation::{PreparationStorageGuard, PreparedRequest};
6use crate::transport::BoundTransport;
7
8impl<T> ClientKernel<T>
9where
10 T: BlockingAuthenticatedTransport + BoundTransport,
11{
12 pub fn execute_blocking_with<'operation, O, R, P, D, F, G, const N: usize>(
14 &self,
15 operation: &'operation O,
16 mut lease: ClientWorkspaceLease<'_, '_, N>,
17 prepare: F,
18 decode: G,
19 ) -> Result<R, ClientExecutionError<P, T::Error, D>>
20 where
21 F: for<'guard> FnOnce(
22 &'operation O,
23 &'guard mut PreparationStorageGuard<'_>,
24 ) -> Result<PreparedRequest<'guard>, P>,
25 G: FnOnce(&'operation O, ClientResponse<'_, '_>) -> Result<R, D>,
26 {
27 let mut parts = lease.parts_mut();
28 parts.clear();
29 let mut storage = PreparationStorageGuard::new(parts.target, parts.request_body);
30 let prepared =
31 prepare(operation, &mut storage).map_err(ClientExecutionError::Preparation)?;
32 let response = prepared
33 .send_blocking(&self.transport, parts.response_body, parts.response_headers)
34 .map_err(ClientExecutionError::Execution)?;
35 decode(operation, ClientResponse::new(prepared, response))
36 .map_err(ClientExecutionError::Decode)
37 }
38}
39
40impl<T> ClientKernel<T>
41where
42 T: AsyncAuthenticatedTransport + BoundTransport + Sync,
43{
44 #[allow(clippy::manual_async_fn)]
46 pub fn execute_async_with<'operation, O, R, P, D, F, G, const N: usize>(
47 &self,
48 operation: &'operation O,
49 mut lease: ClientWorkspaceLease<'_, '_, N>,
50 prepare: F,
51 decode: G,
52 ) -> impl core::future::Future<Output = Result<R, ClientExecutionError<P, T::Error, D>>> + Send
53 where
54 O: Sync,
55 P: Send,
56 R: Send,
57 D: Send,
58 F: for<'guard> FnOnce(
59 &'operation O,
60 &'guard mut PreparationStorageGuard<'_>,
61 ) -> Result<PreparedRequest<'guard>, P>
62 + Send,
63 G: FnOnce(&'operation O, ClientResponse<'_, '_>) -> Result<R, D> + Send,
64 T::Error: Send,
65 {
66 async move {
67 let mut parts = lease.parts_mut();
68 parts.clear();
69 let mut storage = PreparationStorageGuard::new(parts.target, parts.request_body);
70 let prepared =
71 prepare(operation, &mut storage).map_err(ClientExecutionError::Preparation)?;
72 let response = prepared
73 .send_async(&self.transport, parts.response_body, parts.response_headers)
74 .await
75 .map_err(ClientExecutionError::Execution)?;
76 decode(operation, ClientResponse::new(prepared, response))
77 .map_err(ClientExecutionError::Decode)
78 }
79 }
80}
81
82impl<T> ClientKernel<T>
83where
84 T: LocalAsyncAuthenticatedTransport + BoundTransport,
85{
86 pub async fn execute_local_async_with<'operation, O, R, P, D, F, G, const N: usize>(
88 &self,
89 operation: &'operation O,
90 mut lease: ClientWorkspaceLease<'_, '_, N>,
91 prepare: F,
92 decode: G,
93 ) -> Result<R, ClientExecutionError<P, T::Error, D>>
94 where
95 F: for<'guard> FnOnce(
96 &'operation O,
97 &'guard mut PreparationStorageGuard<'_>,
98 ) -> Result<PreparedRequest<'guard>, P>,
99 G: FnOnce(&'operation O, ClientResponse<'_, '_>) -> Result<R, D>,
100 {
101 let mut parts = lease.parts_mut();
102 parts.clear();
103 let mut storage = PreparationStorageGuard::new(parts.target, parts.request_body);
104 let prepared =
105 prepare(operation, &mut storage).map_err(ClientExecutionError::Preparation)?;
106 let response = prepared
107 .send_local_async(&self.transport, parts.response_body, parts.response_headers)
108 .await
109 .map_err(ClientExecutionError::Execution)?;
110 decode(operation, ClientResponse::new(prepared, response))
111 .map_err(ClientExecutionError::Decode)
112 }
113}