Skip to main content

cloud_sdk/client/
execution_custom.rs

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    /// Executes through cleanup-owning provider preparation and decoding hooks.
13    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    /// Send-async equivalent of [`Self::execute_blocking_with`].
45    #[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    /// Local-async equivalent of [`Self::execute_blocking_with`].
87    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}