google_cloud_gax/
options.rs1use crate::backoff_policy::{BackoffPolicy, BackoffPolicyArg};
29use crate::polling_backoff_policy::{PollingBackoffPolicy, PollingBackoffPolicyArg};
30use crate::polling_error_policy::{PollingErrorPolicy, PollingErrorPolicyArg};
31use crate::retry_policy::{RetryPolicy, RetryPolicyArg};
32use crate::retry_throttler::{RetryThrottlerArg, SharedRetryThrottler};
33use std::sync::Arc;
34
35#[derive(Clone, Debug, Default)]
43pub struct RequestOptions {
44 idempotent: Option<bool>,
45 user_agent: Option<String>,
46 attempt_timeout: Option<std::time::Duration>,
47 retry_policy: Option<Arc<dyn RetryPolicy>>,
48 backoff_policy: Option<Arc<dyn BackoffPolicy>>,
49 retry_throttler: Option<SharedRetryThrottler>,
50 polling_error_policy: Option<Arc<dyn PollingErrorPolicy>>,
51 polling_backoff_policy: Option<Arc<dyn PollingBackoffPolicy>>,
52}
53
54impl RequestOptions {
55 pub fn idempotent(&self) -> Option<bool> {
57 self.idempotent
58 }
59
60 pub fn set_idempotency(&mut self, value: bool) {
72 self.idempotent = Some(value);
73 }
74
75 pub fn set_default_idempotency(mut self, default: bool) -> Self {
81 self.idempotent.get_or_insert(default);
82 self
83 }
84
85 pub fn set_user_agent<T: Into<String>>(&mut self, v: T) {
87 self.user_agent = Some(v.into());
88 }
89
90 pub fn user_agent(&self) -> &Option<String> {
92 &self.user_agent
93 }
94
95 pub fn set_attempt_timeout<T: Into<std::time::Duration>>(&mut self, v: T) {
100 self.attempt_timeout = Some(v.into());
101 }
102
103 pub fn attempt_timeout(&self) -> &Option<std::time::Duration> {
105 &self.attempt_timeout
106 }
107
108 pub fn retry_policy(&self) -> &Option<Arc<dyn RetryPolicy>> {
110 &self.retry_policy
111 }
112
113 pub fn set_retry_policy<V: Into<RetryPolicyArg>>(&mut self, v: V) {
115 self.retry_policy = Some(v.into().0);
116 }
117
118 pub fn backoff_policy(&self) -> &Option<Arc<dyn BackoffPolicy>> {
120 &self.backoff_policy
121 }
122
123 pub fn set_backoff_policy<V: Into<BackoffPolicyArg>>(&mut self, v: V) {
125 self.backoff_policy = Some(v.into().0);
126 }
127
128 pub fn retry_throttler(&self) -> &Option<SharedRetryThrottler> {
130 &self.retry_throttler
131 }
132
133 pub fn set_retry_throttler<V: Into<RetryThrottlerArg>>(&mut self, v: V) {
135 self.retry_throttler = Some(v.into().0);
136 }
137
138 pub fn polling_error_policy(&self) -> &Option<Arc<dyn PollingErrorPolicy>> {
140 &self.polling_error_policy
141 }
142
143 pub fn set_polling_error_policy<V: Into<PollingErrorPolicyArg>>(&mut self, v: V) {
145 self.polling_error_policy = Some(v.into().0);
146 }
147
148 pub fn polling_backoff_policy(&self) -> &Option<Arc<dyn PollingBackoffPolicy>> {
150 &self.polling_backoff_policy
151 }
152
153 pub fn set_polling_backoff_policy<V: Into<PollingBackoffPolicyArg>>(&mut self, v: V) {
155 self.polling_backoff_policy = Some(v.into().0);
156 }
157}
158
159pub trait RequestOptionsBuilder: internal::RequestBuilder {
166 fn with_idempotency(self, v: bool) -> Self;
168
169 fn with_user_agent<V: Into<String>>(self, v: V) -> Self;
171
172 fn with_attempt_timeout<V: Into<std::time::Duration>>(self, v: V) -> Self;
177
178 fn with_retry_policy<V: Into<RetryPolicyArg>>(self, v: V) -> Self;
180
181 fn with_backoff_policy<V: Into<BackoffPolicyArg>>(self, v: V) -> Self;
183
184 fn with_retry_throttler<V: Into<RetryThrottlerArg>>(self, v: V) -> Self;
186
187 fn with_polling_error_policy<V: Into<PollingErrorPolicyArg>>(self, v: V) -> Self;
189
190 fn with_polling_backoff_policy<V: Into<PollingBackoffPolicyArg>>(self, v: V) -> Self;
192}
193
194#[doc(hidden)]
198pub mod internal {
199 pub trait RequestBuilder {
205 fn request_options(&mut self) -> &mut super::RequestOptions;
206 }
207}
208
209impl<T> RequestOptionsBuilder for T
211where
212 T: internal::RequestBuilder,
213{
214 fn with_idempotency(mut self, v: bool) -> Self {
215 self.request_options().set_idempotency(v);
216 self
217 }
218
219 fn with_user_agent<V: Into<String>>(mut self, v: V) -> Self {
220 self.request_options().set_user_agent(v);
221 self
222 }
223
224 fn with_attempt_timeout<V: Into<std::time::Duration>>(mut self, v: V) -> Self {
225 self.request_options().set_attempt_timeout(v);
226 self
227 }
228
229 fn with_retry_policy<V: Into<RetryPolicyArg>>(mut self, v: V) -> Self {
230 self.request_options().set_retry_policy(v);
231 self
232 }
233
234 fn with_backoff_policy<V: Into<BackoffPolicyArg>>(mut self, v: V) -> Self {
235 self.request_options().set_backoff_policy(v);
236 self
237 }
238
239 fn with_retry_throttler<V: Into<RetryThrottlerArg>>(mut self, v: V) -> Self {
240 self.request_options().set_retry_throttler(v);
241 self
242 }
243
244 fn with_polling_error_policy<V: Into<PollingErrorPolicyArg>>(mut self, v: V) -> Self {
245 self.request_options().set_polling_error_policy(v);
246 self
247 }
248
249 fn with_polling_backoff_policy<V: Into<PollingBackoffPolicyArg>>(mut self, v: V) -> Self {
250 self.request_options().set_polling_backoff_policy(v);
251 self
252 }
253}
254
255#[cfg(test)]
256mod test {
257 use super::internal::*;
258 use super::*;
259 use crate::exponential_backoff::ExponentialBackoffBuilder;
260 use crate::polling_error_policy;
261 use crate::retry_policy::LimitedAttemptCount;
262 use crate::retry_throttler::AdaptiveThrottler;
263 use std::time::Duration;
264 type Result = std::result::Result<(), Box<dyn std::error::Error>>;
265
266 #[derive(Debug, Default)]
267 struct TestBuilder {
268 request_options: RequestOptions,
269 }
270 impl RequestBuilder for TestBuilder {
271 fn request_options(&mut self) -> &mut RequestOptions {
272 &mut self.request_options
273 }
274 }
275
276 #[test]
277 fn request_options() {
278 let mut opts = RequestOptions::default();
279
280 assert_eq!(opts.idempotent, None);
281 opts.set_idempotency(true);
282 assert_eq!(opts.idempotent(), Some(true));
283 opts.set_idempotency(false);
284 assert_eq!(opts.idempotent(), Some(false));
285
286 opts.set_user_agent("test-only");
287 assert_eq!(opts.user_agent().as_deref(), Some("test-only"));
288 assert_eq!(opts.attempt_timeout(), &None);
289
290 let d = Duration::from_secs(123);
291 opts.set_attempt_timeout(d);
292 assert_eq!(opts.user_agent().as_deref(), Some("test-only"));
293 assert_eq!(opts.attempt_timeout(), &Some(d));
294
295 opts.set_retry_policy(LimitedAttemptCount::new(3));
296 assert!(opts.retry_policy().is_some(), "{opts:?}");
297
298 opts.set_backoff_policy(ExponentialBackoffBuilder::new().clamp());
299 assert!(opts.backoff_policy().is_some(), "{opts:?}");
300
301 opts.set_retry_throttler(AdaptiveThrottler::default());
302 assert!(opts.retry_throttler().is_some(), "{opts:?}");
303
304 opts.set_polling_error_policy(polling_error_policy::Aip194Strict);
305 assert!(opts.polling_error_policy().is_some(), "{opts:?}");
306
307 opts.set_polling_backoff_policy(ExponentialBackoffBuilder::new().clamp());
308 assert!(opts.polling_backoff_policy().is_some(), "{opts:?}");
309 }
310
311 #[test]
312 fn request_options_idempotency() {
313 let opts = RequestOptions::default().set_default_idempotency(true);
314 assert_eq!(opts.idempotent(), Some(true));
315 let opts = opts.set_default_idempotency(false);
316 assert_eq!(opts.idempotent(), Some(true));
317
318 let opts = RequestOptions::default().set_default_idempotency(false);
319 assert_eq!(opts.idempotent(), Some(false));
320 let opts = opts.set_default_idempotency(true);
321 assert_eq!(opts.idempotent(), Some(false));
322 }
323
324 #[test]
325 fn request_options_builder() -> Result {
326 let mut builder = TestBuilder::default();
327 assert_eq!(builder.request_options().user_agent(), &None);
328 assert_eq!(builder.request_options().attempt_timeout(), &None);
329
330 let mut builder = TestBuilder::default().with_idempotency(true);
331 assert_eq!(builder.request_options().idempotent(), Some(true));
332 let mut builder = TestBuilder::default().with_idempotency(false);
333 assert_eq!(builder.request_options().idempotent(), Some(false));
334
335 let mut builder = TestBuilder::default().with_user_agent("test-only");
336 assert_eq!(
337 builder.request_options().user_agent().as_deref(),
338 Some("test-only")
339 );
340 assert_eq!(builder.request_options().attempt_timeout(), &None);
341
342 let d = Duration::from_secs(123);
343 let mut builder = TestBuilder::default().with_attempt_timeout(d);
344 assert_eq!(builder.request_options().user_agent(), &None);
345 assert_eq!(builder.request_options().attempt_timeout(), &Some(d));
346
347 let mut builder = TestBuilder::default().with_retry_policy(LimitedAttemptCount::new(3));
348 assert!(
349 builder.request_options().retry_policy().is_some(),
350 "{builder:?}"
351 );
352
353 let mut builder =
354 TestBuilder::default().with_backoff_policy(ExponentialBackoffBuilder::new().build()?);
355 assert!(
356 builder.request_options().backoff_policy().is_some(),
357 "{builder:?}"
358 );
359
360 let mut builder = TestBuilder::default().with_retry_throttler(AdaptiveThrottler::default());
361 assert!(
362 builder.request_options().retry_throttler().is_some(),
363 "{builder:?}"
364 );
365
366 let mut builder =
367 TestBuilder::default().with_polling_error_policy(polling_error_policy::Aip194Strict);
368 assert!(
369 builder.request_options().polling_error_policy().is_some(),
370 "{builder:?}"
371 );
372
373 let mut builder = TestBuilder::default()
374 .with_polling_backoff_policy(ExponentialBackoffBuilder::new().build()?);
375 assert!(
376 builder.request_options().polling_backoff_policy().is_some(),
377 "{builder:?}"
378 );
379
380 Ok(())
381 }
382}