1use std::{io, net::TcpStream};
2
3#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
4use std::time::Duration;
5
6#[cfg(not(target_family = "wasm"))]
7pub use socket2;
8
9#[derive(Clone, Debug)]
11pub struct TcpSettings {
12 nodelay: bool,
13 #[cfg(not(target_family = "wasm"))]
14 keepalive: Option<socket2::TcpKeepalive>,
15 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
16 user_timeout: Option<Duration>,
17}
18
19impl TcpSettings {
20 pub fn nodelay(&self) -> bool {
22 self.nodelay
23 }
24
25 #[cfg(not(target_family = "wasm"))]
27 pub fn keepalive(&self) -> Option<&socket2::TcpKeepalive> {
28 self.keepalive.as_ref()
29 }
30
31 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
33 pub fn user_timeout(&self) -> Option<Duration> {
34 self.user_timeout
35 }
36
37 pub fn set_nodelay(self, nodelay: bool) -> Self {
39 Self { nodelay, ..self }
40 }
41
42 #[cfg(not(target_family = "wasm"))]
46 pub fn set_keepalive(self, keepalive: socket2::TcpKeepalive) -> Self {
47 Self {
48 keepalive: Some(keepalive),
49 ..self
50 }
51 }
52
53 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
55 pub fn set_user_timeout(self, user_timeout: Duration) -> Self {
56 Self {
57 user_timeout: Some(user_timeout),
58 ..self
59 }
60 }
61}
62
63#[allow(clippy::derivable_impls)]
64impl Default for TcpSettings {
65 fn default() -> Self {
66 Self {
67 nodelay: false,
68 #[cfg(not(target_family = "wasm"))]
69 keepalive: None,
70 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
71 user_timeout: None,
72 }
73 }
74}
75
76pub(crate) fn stream_with_settings(
77 socket: TcpStream,
78 settings: &TcpSettings,
79) -> io::Result<TcpStream> {
80 socket.set_nodelay(settings.nodelay)?;
81 #[cfg(not(target_family = "wasm"))]
82 {
83 let socket2: socket2::Socket = socket.into();
84 if let Some(keepalive) = &settings.keepalive {
85 socket2.set_tcp_keepalive(keepalive)?;
86 }
87 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
88 socket2.set_tcp_user_timeout(settings.user_timeout)?;
89 Ok(socket2.into())
90 }
91 #[cfg(target_family = "wasm")]
92 {
93 Ok(socket)
94 }
95}