Skip to main content

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}