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