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 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}