aws_smithy_runtime_api/client/
waiters.rs1pub mod error {
8    use crate::client::{
9        orchestrator::HttpResponse,
10        result::{ConstructionFailure, SdkError},
11    };
12    use crate::{box_error::BoxError, client::waiters::FinalPoll};
13    use aws_smithy_types::error::{
14        metadata::{ProvideErrorMetadata, EMPTY_ERROR_METADATA},
15        ErrorMetadata,
16    };
17    use std::{fmt, time::Duration};
18
19    #[derive(Debug)]
24    #[non_exhaustive]
25    pub enum WaiterError<O, E> {
26        ConstructionFailure(ConstructionFailure),
30
31        ExceededMaxWait(ExceededMaxWait),
33
34        FailureState(FailureState<O, E>),
43
44        OperationFailed(OperationFailed<E>),
52    }
53
54    impl<O, E> WaiterError<O, E> {
55        pub fn construction_failure(source: impl Into<BoxError>) -> Self {
57            Self::ConstructionFailure(ConstructionFailure::builder().source(source).build())
58        }
59    }
60
61    impl<O, E> std::error::Error for WaiterError<O, E>
62    where
63        O: fmt::Debug,
64        E: std::error::Error + fmt::Debug + 'static,
65    {
66        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
67            match self {
68                Self::ConstructionFailure(inner) => Some(&*inner.source),
69                Self::ExceededMaxWait(_) => None,
70                Self::FailureState(inner) => match &inner.final_poll.result {
71                    Ok(_) => None,
72                    Err(err) => Some(err),
73                },
74                Self::OperationFailed(inner) => Some(&inner.source),
75            }
76        }
77    }
78
79    impl<O, E> fmt::Display for WaiterError<O, E> {
80        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81            match self {
82                Self::ConstructionFailure(_) => f.write_str("failed to construct waiter"),
83                Self::ExceededMaxWait(ctx) => {
84                    write!(f, "exceeded max wait time ({:?})", ctx.max_wait)
85                }
86                Self::FailureState(_) => f.write_str("waiting failed"),
87                Self::OperationFailed(_) => f.write_str("operation failed while waiting"),
88            }
89        }
90    }
91
92    impl<O, E> ProvideErrorMetadata for WaiterError<O, E>
94    where
95        E: ProvideErrorMetadata,
96    {
97        fn meta(&self) -> &ErrorMetadata {
98            match self {
99                WaiterError::ConstructionFailure(_) | WaiterError::ExceededMaxWait(_) => {
100                    &EMPTY_ERROR_METADATA
101                }
102                WaiterError::FailureState(inner) => inner
103                    .final_poll()
104                    .as_result()
105                    .err()
106                    .map(ProvideErrorMetadata::meta)
107                    .unwrap_or(&EMPTY_ERROR_METADATA),
108                WaiterError::OperationFailed(inner) => inner.error().meta(),
109            }
110        }
111    }
112
113    #[derive(Debug)]
115    pub struct ExceededMaxWait {
116        max_wait: Duration,
117        elapsed: Duration,
118        poll_count: u32,
119    }
120
121    impl ExceededMaxWait {
122        pub fn new(max_wait: Duration, elapsed: Duration, poll_count: u32) -> Self {
124            Self {
125                max_wait,
126                elapsed,
127                poll_count,
128            }
129        }
130
131        pub fn max_wait(&self) -> Duration {
133            self.max_wait
134        }
135
136        pub fn elapsed(&self) -> Duration {
138            self.elapsed
139        }
140
141        pub fn poll_count(&self) -> u32 {
143            self.poll_count
144        }
145    }
146
147    #[derive(Debug)]
149    #[non_exhaustive]
150    pub struct FailureState<O, E> {
151        final_poll: FinalPoll<O, E>,
152    }
153
154    impl<O, E> FailureState<O, E> {
155        pub fn new(final_poll: FinalPoll<O, E>) -> Self {
157            Self { final_poll }
158        }
159
160        pub fn final_poll(&self) -> &FinalPoll<O, E> {
162            &self.final_poll
163        }
164
165        pub fn into_final_poll(self) -> FinalPoll<O, E> {
167            self.final_poll
168        }
169    }
170
171    #[derive(Debug)]
173    #[non_exhaustive]
174    pub struct OperationFailed<E> {
175        source: SdkError<E, HttpResponse>,
176    }
177
178    impl<E> OperationFailed<E> {
179        pub fn new(source: SdkError<E, HttpResponse>) -> Self {
181            Self { source }
182        }
183
184        pub fn error(&self) -> &SdkError<E, HttpResponse> {
186            &self.source
187        }
188
189        pub fn into_error(self) -> SdkError<E, HttpResponse> {
191            self.source
192        }
193    }
194}
195
196#[non_exhaustive]
202#[derive(Debug)]
203pub struct FinalPoll<O, E> {
204    result: Result<O, E>,
205}
206
207impl<O, E> FinalPoll<O, E> {
208    pub fn new(result: Result<O, E>) -> Self {
210        Self { result }
211    }
212
213    pub fn into_result(self) -> Result<O, E> {
215        self.result
216    }
217
218    pub fn as_result(&self) -> Result<&O, &E> {
220        self.result.as_ref()
221    }
222
223    pub fn map<O2, F: FnOnce(O) -> O2>(self, mapper: F) -> FinalPoll<O2, E> {
225        FinalPoll::new(self.result.map(mapper))
226    }
227
228    pub fn map_err<E2, F: FnOnce(E) -> E2>(self, mapper: F) -> FinalPoll<O, E2> {
230        FinalPoll::new(self.result.map_err(mapper))
231    }
232}