Skip to main content

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}