From a07fde42c3f88afd55520617e408c78b26ced563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Gr=C3=A4fe?= Date: Thu, 27 Apr 2023 14:32:25 +0200 Subject: [PATCH] [refactor] config: Use dedicated functions to set options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With public members in the config structs the public API breaks each time we're adding new options as the users MUST or MUST NOT add ".. Default::default()" depending on wheter they're setting all options or not. So adding new options breaks for those users who use all options. This change hides the members form the users and replaces access by dedicated setter functions for each option so adding new options does not break API in the future. (This change obviously is an API break in itself.) Signed-off-by: Konrad Gräfe --- src/adapters/framed_tcp.rs | 18 +++++++++++-- src/adapters/tcp.rs | 18 +++++++++++-- src/adapters/udp.rs | 54 ++++++++++++++++++++++++++++++++------ src/network.rs | 4 +-- 4 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/adapters/framed_tcp.rs b/src/adapters/framed_tcp.rs index fff93b3..15e9f42 100644 --- a/src/adapters/framed_tcp.rs +++ b/src/adapters/framed_tcp.rs @@ -24,14 +24,28 @@ const INPUT_BUFFER_SIZE: usize = u16::MAX as usize; // 2^16 - 1 #[derive(Clone, Debug, Default)] pub struct FramedTcpConnectConfig { + keepalive: Option, +} + +impl FramedTcpConnectConfig { /// Enables TCP keepalive settings on the socket. - pub keepalive: Option, + pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self { + self.keepalive = Some(keepalive); + self + } } #[derive(Clone, Debug, Default)] pub struct FramedTcpListenConfig { + keepalive: Option, +} + +impl FramedTcpListenConfig { /// Enables TCP keepalive settings on client connection sockets. - pub keepalive: Option, + pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self { + self.keepalive = Some(keepalive); + self + } } pub(crate) struct FramedTcpAdapter; diff --git a/src/adapters/tcp.rs b/src/adapters/tcp.rs index a781d0d..4edebc4 100644 --- a/src/adapters/tcp.rs +++ b/src/adapters/tcp.rs @@ -25,14 +25,28 @@ pub const INPUT_BUFFER_SIZE: usize = u16::MAX as usize; // 2^16 - 1 #[derive(Clone, Debug, Default)] pub struct TcpConnectConfig { + keepalive: Option, +} + +impl TcpConnectConfig { /// Enables TCP keepalive settings on the socket. - pub keepalive: Option, + pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self { + self.keepalive = Some(keepalive); + self + } } #[derive(Clone, Debug, Default)] pub struct TcpListenConfig { + keepalive: Option, +} + +impl TcpListenConfig { /// Enables TCP keepalive settings on client connection sockets. - pub keepalive: Option, + pub fn with_keepalive(mut self, keepalive: TcpKeepalive) -> Self { + self.keepalive = Some(keepalive); + self + } } pub(crate) struct TcpAdapter; diff --git a/src/adapters/udp.rs b/src/adapters/udp.rs index d1bbe15..35b4695 100644 --- a/src/adapters/udp.rs +++ b/src/adapters/udp.rs @@ -39,22 +39,41 @@ pub const MAX_LOCAL_PAYLOAD_LEN: usize = 9216 - 20 - 8; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct UdpConnectConfig { + source_address: SocketAddr, + broadcast: bool, + reuse_address: bool, + reuse_port: bool, +} + +impl UdpConnectConfig { /// Specify the source address and port. - pub source_address: SocketAddr, + pub fn with_source_address(mut self, addr: SocketAddr) -> Self { + self.source_address = addr; + self + } /// Enables the socket capabilities to send broadcast messages. - pub broadcast: bool, + pub fn with_broadcast(mut self) -> Self { + self.broadcast = true; + self + } /// Set value for the `SO_REUSEADDR` option on this socket. This indicates that futher calls to /// `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may /// bind even when there’s a socket already listening on this port. - pub reuse_address: bool, + pub fn with_reuse_address(mut self) -> Self { + self.reuse_address = true; + self + } /// Set value for the `SO_REUSEPORT` option on this socket. This indicates that further calls /// to `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may /// bind even when there’s a socket already listening on this port. This option is always-on on /// Windows and cannot be configured. - pub reuse_port: bool, + pub fn with_reuse_port(mut self) -> Self { + self.reuse_port = true; + self + } } impl Default for UdpConnectConfig { @@ -70,26 +89,45 @@ impl Default for UdpConnectConfig { #[derive(Clone, PartialEq, Eq, Hash, Debug, Default)] pub struct UdpListenConfig { + send_broadcasts: bool, + receive_broadcasts: bool, + reuse_address: bool, + reuse_port: bool, +} + +impl UdpListenConfig { /// Enables the socket capabilities to send broadcast messages when the listening socket is /// also used for sending with /// [`Endpoint::from_listener`](crate::network::Endpoint::from_listener). - pub send_broadcasts: bool, + pub fn with_send_broadcasts(mut self) -> Self { + self.send_broadcasts = true; + self + } /// On Windows, when listening on a specific IP address, the sockets also receives /// corresponding subnet broadcasts and global broadcasts ([`std::net::Ipv4Addr::BROADCAST`]) /// received on the interface matching the IP. When this option is set, message-io mimics this /// behavior on Linux. - pub receive_broadcasts: bool, + pub fn with_receive_broadcasts(mut self) -> Self { + self.receive_broadcasts = true; + self + } /// Set value for the `SO_REUSEADDR` option on this socket. This indicates that futher calls to /// `bind` may allow reuse of local addresses. - pub reuse_address: bool, + pub fn with_reuse_address(mut self) -> Self { + self.reuse_address = true; + self + } /// Set value for the `SO_REUSEPORT` option on this socket. This indicates that further calls /// to `bind` may allow reuse of local addresses. For IPv4 sockets this means that a socket may /// bind even when there’s a socket already listening on this port. This option is always-on /// on Windows and cannot be configured. - pub reuse_port: bool, + pub fn with_reuse_port(mut self) -> Self { + self.reuse_port = true; + self + } } pub(crate) struct UdpAdapter; diff --git a/src/network.rs b/src/network.rs index 78326ba..1b5eafd 100644 --- a/src/network.rs +++ b/src/network.rs @@ -126,7 +126,7 @@ impl NetworkController { /// let (handler, listener) = node::split(); /// handler.signals().send_with_timer((), std::time::Duration::from_secs(1)); /// - /// let config = UdpConnectConfig { broadcast: true, ..Default::default() }; + /// let config = UdpConnectConfig::default().with_broadcast(); /// let addr = "255.255.255.255:7777"; /// let (conn_endpoint, _) = handler.network().connect_with(TransportConnect::Udp(config), addr).unwrap(); /// // The socket could not be able to send yet. @@ -226,7 +226,7 @@ impl NetworkController { /// let (handler, listener) = node::split(); /// handler.signals().send_with_timer((), std::time::Duration::from_secs(1)); /// - /// let config = UdpConnectConfig { broadcast: true, ..Default::default() }; + /// let config = UdpConnectConfig::default().with_broadcast(); /// let addr = "255.255.255.255:7777"; /// match handler.network().connect_sync_with(TransportConnect::Udp(config), addr) { /// Ok((endpoint, _)) => {