qubit_http/request/http_request_retry_override.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Request-level retry override options.
11
12use crate::HttpRetryMethodPolicy;
13
14/// Per-request overrides for the client retry strategy.
15///
16/// This type allows callers to:
17/// - force-enable retry even when client-level retry is disabled;
18/// - force-disable retry for one request;
19/// - override the retryable-method policy for one request;
20/// - optionally honor `Retry-After` on retryable status responses (`429` and
21/// `5xx`).
22#[derive(Debug, Clone, PartialEq, Eq, Default)]
23pub struct HttpRequestRetryOverride {
24 /// Force retry on for this request (unless explicitly force-disabled).
25 force_enable: bool,
26 /// Force retry off for this request.
27 force_disable: bool,
28 /// Optional method-policy override for this request.
29 method_policy: Option<HttpRetryMethodPolicy>,
30 /// Whether to honor `Retry-After` on retryable status responses.
31 honor_retry_after: bool,
32}
33
34impl HttpRequestRetryOverride {
35 /// Creates an empty override that follows client-level retry settings.
36 ///
37 /// # Returns
38 /// New [`HttpRequestRetryOverride`] with all per-request overrides disabled.
39 pub fn new() -> Self {
40 Self::default()
41 }
42
43 /// Enables force-retry for this request and clears force-disable.
44 ///
45 /// # Returns
46 /// Updated override for chaining.
47 pub fn force_enable(mut self) -> Self {
48 self.force_enable = true;
49 self.force_disable = false;
50 self
51 }
52
53 /// Enables force-disable for this request and clears force-enable.
54 ///
55 /// # Returns
56 /// Updated override for chaining.
57 pub fn force_disable(mut self) -> Self {
58 self.force_disable = true;
59 self.force_enable = false;
60 self
61 }
62
63 /// Sets the per-request retryable-method policy override.
64 ///
65 /// # Parameters
66 /// - `policy`: Method policy to use for this request.
67 ///
68 /// # Returns
69 /// Updated override for chaining.
70 pub fn with_method_policy(mut self, policy: HttpRetryMethodPolicy) -> Self {
71 self.method_policy = Some(policy);
72 self
73 }
74
75 /// Enables or disables honoring `Retry-After` for this request.
76 ///
77 /// # Parameters
78 /// - `enabled`: `true` to honor `Retry-After` on retryable status
79 /// responses (`429` and `5xx`).
80 ///
81 /// # Returns
82 /// Updated override for chaining.
83 pub fn with_honor_retry_after(mut self, enabled: bool) -> Self {
84 self.honor_retry_after = enabled;
85 self
86 }
87
88 /// Returns whether force-enable is active for this request.
89 ///
90 /// # Returns
91 /// `true` when retry is force-enabled at request level.
92 pub fn is_force_enable(&self) -> bool {
93 self.force_enable
94 }
95
96 /// Returns whether force-disable is active for this request.
97 ///
98 /// # Returns
99 /// `true` when retry is force-disabled at request level.
100 pub fn is_force_disable(&self) -> bool {
101 self.force_disable
102 }
103
104 /// Returns the per-request method-policy override, if present.
105 ///
106 /// # Returns
107 /// Optional override for [`HttpRetryMethodPolicy`].
108 pub fn method_policy(&self) -> Option<HttpRetryMethodPolicy> {
109 self.method_policy
110 }
111
112 /// Returns whether `Retry-After` should be honored for this request.
113 ///
114 /// # Returns
115 /// `true` when this request should honor `Retry-After` on retryable status
116 /// responses (`429` and `5xx`).
117 pub fn should_honor_retry_after(&self) -> bool {
118 self.honor_retry_after
119 }
120
121 /// Resolves request-level force-enable/force-disable against client defaults.
122 ///
123 /// # Parameters
124 /// - `client_enabled`: Client-level retry enabled flag.
125 ///
126 /// # Returns
127 /// Effective retry-enabled flag for this request.
128 pub(crate) fn resolve_enabled(&self, client_enabled: bool) -> bool {
129 if self.force_disable {
130 false
131 } else if self.force_enable {
132 true
133 } else {
134 client_enabled
135 }
136 }
137
138 /// Resolves effective method policy from request-level override + client policy.
139 ///
140 /// # Parameters
141 /// - `client_policy`: Client-level method policy.
142 ///
143 /// # Returns
144 /// Effective method policy for this request.
145 pub(crate) fn resolve_method_policy(
146 &self,
147 client_policy: HttpRetryMethodPolicy,
148 ) -> HttpRetryMethodPolicy {
149 self.method_policy.unwrap_or(client_policy)
150 }
151}