tlq_client/config.rs
1use crate::client::TlqClient;
2use std::time::Duration;
3
4/// Configuration settings for TLQ client connections.
5///
6/// This struct contains all the configurable parameters for connecting to and
7/// interacting with a TLQ server, including network settings and retry behavior.
8///
9/// # Default Values
10///
11/// - `host`: "localhost"
12/// - `port`: 1337
13/// - `timeout`: 30 seconds
14/// - `max_retries`: 3
15/// - `retry_delay`: 100 milliseconds (base delay for exponential backoff)
16///
17/// # Examples
18///
19/// ```
20/// use tlq_client::{Config, ConfigBuilder};
21/// use std::time::Duration;
22///
23/// // Using defaults
24/// let default_config = Config::default();
25/// assert_eq!(default_config.host, "localhost");
26/// assert_eq!(default_config.port, 1337);
27///
28/// // Using builder pattern
29/// let custom_config = ConfigBuilder::new()
30/// .host("queue.example.com")
31/// .port(8080)
32/// .timeout(Duration::from_secs(60))
33/// .max_retries(5)
34/// .build_config();
35/// ```
36#[derive(Debug, Clone)]
37pub struct Config {
38 /// Hostname or IP address of the TLQ server
39 pub host: String,
40 /// Port number of the TLQ server
41 pub port: u16,
42 /// Maximum time to wait for a single request to complete
43 pub timeout: Duration,
44 /// Maximum number of retry attempts for failed operations
45 pub max_retries: u32,
46 /// Base delay between retry attempts (exponential backoff multiplier)
47 pub retry_delay: Duration,
48}
49
50impl Default for Config {
51 fn default() -> Self {
52 Self {
53 host: "localhost".to_string(),
54 port: 1337,
55 timeout: Duration::from_secs(30),
56 max_retries: 3,
57 retry_delay: Duration::from_millis(100),
58 }
59 }
60}
61
62/// Builder for creating [`Config`] instances with custom settings.
63///
64/// `ConfigBuilder` provides a fluent interface for constructing [`Config`] objects
65/// with specific settings. All methods return `self` to enable method chaining.
66/// Call [`build()`](Self::build) to create the final [`Config`] instance.
67///
68/// # Examples
69///
70/// ```
71/// use tlq_client::ConfigBuilder;
72/// use std::time::Duration;
73///
74/// let config = ConfigBuilder::new()
75/// .host("queue.example.com")
76/// .port(8080)
77/// .timeout_ms(5000) // 5 second timeout
78/// .max_retries(2) // Only retry twice
79/// .retry_delay_ms(250) // 250ms base delay
80/// .build_config();
81///
82/// assert_eq!(config.host, "queue.example.com");
83/// assert_eq!(config.port, 8080);
84/// assert_eq!(config.timeout, Duration::from_millis(5000));
85/// ```
86pub struct ConfigBuilder {
87 config: Config,
88}
89
90impl ConfigBuilder {
91 /// Creates a new `ConfigBuilder` with default settings.
92 ///
93 /// Equivalent to `Config::default()` but allows method chaining.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use tlq_client::ConfigBuilder;
99 ///
100 /// let builder = ConfigBuilder::new();
101 /// let _client = builder.build();
102 /// ```
103 pub fn new() -> Self {
104 Self {
105 config: Config::default(),
106 }
107 }
108
109 /// Sets the TLQ server hostname or IP address.
110 ///
111 /// # Arguments
112 ///
113 /// * `host` - Any type that can be converted to `String`
114 ///
115 /// # Examples
116 ///
117 /// ```
118 /// use tlq_client::ConfigBuilder;
119 ///
120 /// let config = ConfigBuilder::new()
121 /// .host("queue.example.com")
122 /// .build_config();
123 /// assert_eq!(config.host, "queue.example.com");
124 /// ```
125 pub fn host(mut self, host: impl Into<String>) -> Self {
126 self.config.host = host.into();
127 self
128 }
129
130 /// Sets the TLQ server port number.
131 ///
132 /// # Arguments
133 ///
134 /// * `port` - Port number (1-65535)
135 ///
136 /// # Examples
137 ///
138 /// ```
139 /// use tlq_client::ConfigBuilder;
140 ///
141 /// let config = ConfigBuilder::new()
142 /// .port(8080)
143 /// .build_config();
144 /// assert_eq!(config.port, 8080);
145 /// ```
146 pub fn port(mut self, port: u16) -> Self {
147 self.config.port = port;
148 self
149 }
150
151 /// Sets the request timeout duration.
152 ///
153 /// # Arguments
154 ///
155 /// * `timeout` - Maximum time to wait for each request
156 ///
157 /// # Examples
158 ///
159 /// ```
160 /// use tlq_client::ConfigBuilder;
161 /// use std::time::Duration;
162 ///
163 /// let config = ConfigBuilder::new()
164 /// .timeout(Duration::from_secs(60))
165 /// .build_config();
166 /// assert_eq!(config.timeout, Duration::from_secs(60));
167 /// ```
168 pub fn timeout(mut self, timeout: Duration) -> Self {
169 self.config.timeout = timeout;
170 self
171 }
172
173 /// Sets the request timeout in milliseconds.
174 ///
175 /// Convenience method equivalent to `timeout(Duration::from_millis(ms))`.
176 ///
177 /// # Arguments
178 ///
179 /// * `ms` - Timeout in milliseconds
180 ///
181 /// # Examples
182 ///
183 /// ```
184 /// use tlq_client::ConfigBuilder;
185 /// use std::time::Duration;
186 ///
187 /// let config = ConfigBuilder::new()
188 /// .timeout_ms(5000) // 5 seconds
189 /// .build_config();
190 /// assert_eq!(config.timeout, Duration::from_millis(5000));
191 /// ```
192 pub fn timeout_ms(mut self, ms: u64) -> Self {
193 self.config.timeout = Duration::from_millis(ms);
194 self
195 }
196
197 /// Sets the maximum number of retry attempts.
198 ///
199 /// When a retryable error occurs, the client will retry the operation
200 /// up to this many times before giving up.
201 ///
202 /// # Arguments
203 ///
204 /// * `retries` - Maximum retry attempts (0 disables retries)
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// use tlq_client::ConfigBuilder;
210 ///
211 /// let config = ConfigBuilder::new()
212 /// .max_retries(5)
213 /// .build_config();
214 /// assert_eq!(config.max_retries, 5);
215 /// ```
216 pub fn max_retries(mut self, retries: u32) -> Self {
217 self.config.max_retries = retries;
218 self
219 }
220
221 /// Sets the base retry delay duration.
222 ///
223 /// The actual delay between retries uses exponential backoff:
224 /// delay = base_delay × 2^attempt_number
225 ///
226 /// # Arguments
227 ///
228 /// * `delay` - Base delay for exponential backoff
229 ///
230 /// # Examples
231 ///
232 /// ```
233 /// use tlq_client::ConfigBuilder;
234 /// use std::time::Duration;
235 ///
236 /// let config = ConfigBuilder::new()
237 /// .retry_delay(Duration::from_millis(500))
238 /// .build_config();
239 /// assert_eq!(config.retry_delay, Duration::from_millis(500));
240 /// ```
241 pub fn retry_delay(mut self, delay: Duration) -> Self {
242 self.config.retry_delay = delay;
243 self
244 }
245
246 /// Sets the base retry delay in milliseconds.
247 ///
248 /// Convenience method equivalent to `retry_delay(Duration::from_millis(ms))`.
249 ///
250 /// # Arguments
251 ///
252 /// * `ms` - Base delay in milliseconds
253 ///
254 /// # Examples
255 ///
256 /// ```
257 /// use tlq_client::ConfigBuilder;
258 /// use std::time::Duration;
259 ///
260 /// let config = ConfigBuilder::new()
261 /// .retry_delay_ms(200) // 200ms base delay
262 /// .build_config();
263 /// assert_eq!(config.retry_delay, Duration::from_millis(200));
264 /// ```
265 pub fn retry_delay_ms(mut self, ms: u64) -> Self {
266 self.config.retry_delay = Duration::from_millis(ms);
267 self
268 }
269
270 /// Builds and returns a [`TlqClient`] instance.
271 ///
272 /// Consumes the builder and creates a client with the specified settings.
273 ///
274 /// # Examples
275 ///
276 /// ```no_run
277 /// use tlq_client::ConfigBuilder;
278 ///
279 /// let client = ConfigBuilder::new()
280 /// .host("localhost")
281 /// .port(1337)
282 /// .max_retries(3)
283 /// .build();
284 /// ```
285 pub fn build(self) -> TlqClient {
286 TlqClient::with_config(self.config)
287 }
288
289 /// Builds and returns the [`Config`] instance without creating a client.
290 ///
291 /// Use this when you need the configuration object itself, for example
292 /// to pass to [`TlqClient::with_config`](crate::TlqClient::with_config).
293 ///
294 /// # Examples
295 ///
296 /// ```
297 /// use tlq_client::ConfigBuilder;
298 ///
299 /// let config = ConfigBuilder::new()
300 /// .host("localhost")
301 /// .port(1337)
302 /// .build_config();
303 /// assert_eq!(config.host, "localhost");
304 /// ```
305 pub fn build_config(self) -> Config {
306 self.config
307 }
308}
309
310impl Default for ConfigBuilder {
311 fn default() -> Self {
312 Self::new()
313 }
314}