bacnet_rs/client/config.rs
1//! Configuration and builder for the high-level BACnet client.
2//!
3//! [`ClientConfig`] holds the parameters used to construct a
4//! [`BacnetClient`](super::BacnetClient): the local interface/port to bind, the
5//! per-request timeout, and how many times to retry. Use
6//! [`BacnetClient::builder`](super::BacnetClient::builder) to construct a client
7//! fluently:
8//!
9//! ```rust,no_run
10//! use bacnet_rs::client::BacnetClient;
11//! use std::time::Duration;
12//!
13//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
14//! let client = BacnetClient::builder()
15//! .local_addr("0.0.0.0")
16//! .port(0)
17//! .timeout(Duration::from_secs(3))
18//! .retries(2)
19//! .build()?;
20//! # let _ = client;
21//! # Ok(())
22//! # }
23//! ```
24
25use std::time::Duration;
26
27use super::{BacnetClient, ClientError};
28
29/// Default per-request timeout used when none is configured.
30pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
31
32/// Default host to bind to (all interfaces, OS-assigned ephemeral port).
33pub const DEFAULT_HOST: &str = "0.0.0.0";
34
35/// Configuration parameters for a [`BacnetClient`](super::BacnetClient).
36///
37/// Construct one via [`BacnetClient::builder`](super::BacnetClient::builder)
38/// rather than directly; the builder applies sensible defaults.
39#[derive(Debug, Clone)]
40pub struct ClientConfig {
41 /// Local host/interface to bind the UDP socket to.
42 pub host: String,
43 /// Local UDP port to bind. `0` lets the OS assign an ephemeral port.
44 pub port: u16,
45 /// How long to wait for a response before giving up.
46 pub timeout: Duration,
47 /// Number of times to retry a request after the first attempt times out.
48 ///
49 /// Currently stored for use by later request paths; the existing methods
50 /// do not yet retry.
51 pub retries: u8,
52}
53
54impl Default for ClientConfig {
55 fn default() -> Self {
56 Self {
57 host: DEFAULT_HOST.to_string(),
58 port: 0,
59 timeout: DEFAULT_TIMEOUT,
60 retries: 0,
61 }
62 }
63}
64
65impl ClientConfig {
66 /// The address string (`host:port`) the socket will bind to.
67 pub fn bind_addr(&self) -> String {
68 format!("{}:{}", self.host, self.port)
69 }
70}
71
72/// Fluent builder for a [`BacnetClient`](super::BacnetClient).
73///
74/// Obtain one from [`BacnetClient::builder`](super::BacnetClient::builder).
75#[derive(Debug, Clone, Default)]
76pub struct ClientBuilder {
77 config: ClientConfig,
78}
79
80impl ClientBuilder {
81 /// Create a builder with default configuration.
82 pub fn new() -> Self {
83 Self::default()
84 }
85
86 /// Set the local host/interface to bind to (default `"0.0.0.0"`).
87 pub fn local_addr(mut self, host: impl Into<String>) -> Self {
88 self.config.host = host.into();
89 self
90 }
91
92 /// Set the local UDP port to bind (default `0`, an OS-assigned port).
93 pub fn port(mut self, port: u16) -> Self {
94 self.config.port = port;
95 self
96 }
97
98 /// Set the per-request timeout (default 5 seconds).
99 pub fn timeout(mut self, timeout: Duration) -> Self {
100 self.config.timeout = timeout;
101 self
102 }
103
104 /// Set the number of retries after an initial timeout (default `0`).
105 pub fn retries(mut self, retries: u8) -> Self {
106 self.config.retries = retries;
107 self
108 }
109
110 /// Consume the builder and bind the client's socket.
111 pub fn build(self) -> Result<BacnetClient, ClientError> {
112 BacnetClient::from_config(self.config)
113 }
114}