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