Skip to main content

hick_compio/
options.rs

1//! Caller-facing construction options for [`Endpoint`](crate::Endpoint).
2//!
3//! Mirrors the public shape of `hick-reactor::ServerOptions` so callers can
4//! move between the two crates without re-learning the surface.
5
6use mdns_proto::EndpointConfig;
7
8/// Build-time configuration for an mDNS [`Endpoint`](crate::Endpoint).
9///
10/// The defaults bind on **one** interface for both IPv4 and IPv6: the first
11/// up + multicast-capable, non-loopback interface reported by
12/// [`getifs::interfaces`] that has a usable address for each enabled family,
13/// falling back to the loopback interface if no other is eligible. Use
14/// [`Self::with_interface_index`] to pin a specific interface.
15#[derive(Debug, Clone)]
16pub struct ServerOptions {
17  pub(crate) ipv4: bool,
18  pub(crate) ipv6: bool,
19  pub(crate) interface_index: Option<u32>,
20  pub(crate) max_payload_size: usize,
21  pub(crate) max_recv_packet_size: usize,
22  pub(crate) endpoint_config: EndpointConfig,
23}
24
25impl Default for ServerOptions {
26  #[inline]
27  fn default() -> Self {
28    Self::new()
29  }
30}
31
32impl ServerOptions {
33  /// Build a new options bundle with defaults.
34  #[inline]
35  pub fn new() -> Self {
36    Self {
37      ipv4: true,
38      ipv6: true,
39      interface_index: None,
40      max_payload_size: 1500,
41      max_recv_packet_size: 9000,
42      endpoint_config: EndpointConfig::new(),
43    }
44  }
45
46  /// Whether IPv4 is enabled.
47  #[inline]
48  pub const fn ipv4(&self) -> bool {
49    self.ipv4
50  }
51
52  /// Whether IPv6 is enabled.
53  #[inline]
54  pub const fn ipv6(&self) -> bool {
55    self.ipv6
56  }
57
58  /// The pinned interface index, if any.
59  #[inline]
60  pub const fn interface_index(&self) -> Option<u32> {
61    self.interface_index
62  }
63
64  /// Maximum outgoing-packet buffer size. RFC 6762 §17 recommends staying
65  /// within the path MTU on send (~1500 bytes for Ethernet).
66  #[inline]
67  pub const fn max_payload_size(&self) -> usize {
68    self.max_payload_size
69  }
70
71  /// Maximum size of an inbound mDNS datagram that we will fully receive
72  /// without truncation. RFC 6762 §17 says implementations MUST be prepared
73  /// to receive messages up to 9000 bytes.
74  #[inline]
75  pub const fn max_recv_packet_size(&self) -> usize {
76    self.max_recv_packet_size
77  }
78
79  /// The proto-layer [`EndpointConfig`].
80  #[inline]
81  pub const fn endpoint_config(&self) -> &EndpointConfig {
82    &self.endpoint_config
83  }
84
85  /// Enable or disable IPv4. At least one of v4/v6 must remain enabled.
86  #[inline]
87  #[must_use]
88  pub const fn with_ipv4(mut self, enable: bool) -> Self {
89    self.ipv4 = enable;
90    self
91  }
92
93  /// Enable or disable IPv6.
94  #[inline]
95  #[must_use]
96  pub const fn with_ipv6(mut self, enable: bool) -> Self {
97    self.ipv6 = enable;
98    self
99  }
100
101  /// Pin the listener to a specific interface (by OS index). When `None`
102  /// (the default), the first multicast-capable, non-loopback interface is
103  /// picked.
104  #[inline]
105  #[must_use]
106  pub const fn with_interface_index(mut self, idx: Option<u32>) -> Self {
107    self.interface_index = idx;
108    self
109  }
110
111  /// Override the maximum outgoing-packet buffer size.
112  #[inline]
113  #[must_use]
114  pub const fn with_max_payload_size(mut self, size: usize) -> Self {
115    self.max_payload_size = size;
116    self
117  }
118
119  /// Override the inbound receive buffer size.
120  #[inline]
121  #[must_use]
122  pub const fn with_max_recv_packet_size(mut self, size: usize) -> Self {
123    self.max_recv_packet_size = size;
124    self
125  }
126
127  /// Override the proto-layer [`EndpointConfig`].
128  #[inline]
129  #[must_use]
130  pub fn with_endpoint_config(mut self, cfg: EndpointConfig) -> Self {
131    self.endpoint_config = cfg;
132    self
133  }
134}
135
136#[cfg(test)]
137mod tests;