Skip to content

Commit

Permalink
Generate ApplyTcpOptionsError types and impls
Browse files Browse the repository at this point in the history
  • Loading branch information
hulthe committed Apr 2, 2024
1 parent 7b8aa13 commit 7cd3a45
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 74 deletions.
62 changes: 56 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ lazy_static = "1.4.0"
# pulled in when built as a library.
env_logger = { version = "0.10.0", optional = true }
cadence = { version = "1.0.0", optional = true }
thiserror = "1.0.58"
strum = { version = "0.26.2", features = ["derive"] }

[target.'cfg(target_os = "linux")'.dependencies]
nix = { version = "0.27.1", features = ["socket"] }
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ mod forward_traffic;
mod logging;
mod tcp_options;

pub use tcp_options::{ApplyTcpOptionsError, TcpOptions};
pub use tcp_options::{ApplyTcpOptionsError, ApplyTcpOptionsErrorKind, TcpOptions};

/// Helper trait for `Result<Infallible, E>` types. Allows getting the `E` value
/// in a way that is guaranteed to not panic.
Expand Down
86 changes: 19 additions & 67 deletions src/tcp_options.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#[cfg(target_os = "linux")]
use nix::sys::socket::{getsockopt, setsockopt, sockopt};
use std::fmt;
use std::io;
use std::time::Duration;
use tokio::net::{TcpSocket, TcpStream};
Expand Down Expand Up @@ -36,80 +35,33 @@ pub struct TcpOptions {
}

/// Represents a failure to apply socket options to the TCP socket.
#[derive(Debug)]
pub struct ApplyTcpOptionsError(ApplyTcpOptionsErrorInternal);
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct ApplyTcpOptionsError(#[from] ApplyTcpOptionsErrorInternal);

#[derive(Debug)]
#[derive(Debug, thiserror::Error, strum::EnumDiscriminants)]
#[strum_discriminants(vis(pub))]
#[strum_discriminants(name(ApplyTcpOptionsErrorKind))]
enum ApplyTcpOptionsErrorInternal {
RecvBuffer(io::Error),
SendBuffer(io::Error),
#[error("Failed to get/set TCP_RCVBUF")]
#[strum_discriminants(doc = "Failed to get/set TCP_RCVBUF")]
RecvBuffer(#[source] io::Error),
#[error("Failed to get/set TCP_SNDBUF")]
#[strum_discriminants(doc = "Failed to get/set TCP_SNDBUF")]
SendBuffer(#[source] io::Error),
#[cfg(target_os = "linux")]
Mark(nix::Error),
TcpNoDelay(io::Error),
}

/// A list specifying what failed when applying the TCP options.
#[derive(Debug, Copy, Clone)]
#[non_exhaustive]
pub enum ApplyTcpOptionsErrorKind {
/// Failed to get/set TCP_RCVBUF
RecvBuffer,

/// Failed to get/set TCP_SNDBUF
SendBuffer,

/// Failed to get/set SO_MARK
#[cfg(target_os = "linux")]
Mark,

/// Failed to get/set TCP_NODELAY
TcpNoDelay,
#[error("Failed to get/set SO_MARK")]
#[strum_discriminants(doc = "Failed to get/set SO_MARK")]
Mark(#[source] nix::Error),
#[error("Failed to get/set TCP_NODELAY")]
#[strum_discriminants(doc = "Failed to get/set TCP_NODELAY")]
TcpNoDelay(#[source] io::Error),
}

impl ApplyTcpOptionsError {
/// Returns the kind of error that happened as an enum
pub fn kind(&self) -> ApplyTcpOptionsErrorKind {
use ApplyTcpOptionsErrorInternal::*;
match self.0 {
RecvBuffer(_) => ApplyTcpOptionsErrorKind::RecvBuffer,
SendBuffer(_) => ApplyTcpOptionsErrorKind::SendBuffer,
#[cfg(target_os = "linux")]
Mark(_) => ApplyTcpOptionsErrorKind::Mark,
TcpNoDelay(_) => ApplyTcpOptionsErrorKind::TcpNoDelay,
}
}
}

impl From<ApplyTcpOptionsErrorInternal> for ApplyTcpOptionsError {
fn from(value: ApplyTcpOptionsErrorInternal) -> Self {
Self(value)
}
}

impl fmt::Display for ApplyTcpOptionsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ApplyTcpOptionsErrorInternal::*;
match self.0 {
RecvBuffer(_) => "Failed to get/set TCP_RCVBUF",
SendBuffer(_) => "Failed to get/set TCP_SNDBUF",
#[cfg(target_os = "linux")]
Mark(_) => "Failed to get/set SO_MARK",
TcpNoDelay(_) => "Failed to get/set TCP_NODELAY",
}
.fmt(f)
}
}

impl std::error::Error for ApplyTcpOptionsError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use ApplyTcpOptionsErrorInternal::*;
match &self.0 {
RecvBuffer(e) => Some(e),
SendBuffer(e) => Some(e),
#[cfg(target_os = "linux")]
Mark(e) => Some(e),
TcpNoDelay(e) => Some(e),
}
ApplyTcpOptionsErrorKind::from(&self.0)
}
}

Expand Down

0 comments on commit 7cd3a45

Please sign in to comment.