use std::{io, path::PathBuf};
pub type ServerResult<T> = Result<T, ServerError>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ServerError {
#[error("TLS material load failed ({kind}) at `{path}`: {reason}")]
TlsLoad {
kind: TlsKind,
path: PathBuf,
reason: String,
},
#[error("invalid listener address `{addr}`: {reason}")]
ListenerAddress { addr: String, reason: String },
#[error("middleware script not found: `{path}`")]
MiddlewareMissing { path: PathBuf },
#[error("failed to compile middleware `{path}`: {reason}")]
MiddlewareCompile { path: PathBuf, reason: String },
#[error("i/o error: {0}")]
Io(#[from] io::Error),
#[error(transparent)]
Config(#[from] apimock_config::ConfigError),
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ServerErrorKind {
TlsLoad,
ListenerAddress,
MiddlewareMissing,
MiddlewareCompile,
Io,
Config,
}
impl ServerError {
pub fn kind(&self) -> ServerErrorKind {
match self {
ServerError::TlsLoad { .. } => ServerErrorKind::TlsLoad,
ServerError::ListenerAddress { .. } => ServerErrorKind::ListenerAddress,
ServerError::MiddlewareMissing { .. } => ServerErrorKind::MiddlewareMissing,
ServerError::MiddlewareCompile { .. } => ServerErrorKind::MiddlewareCompile,
ServerError::Io(_) => ServerErrorKind::Io,
ServerError::Config(_) => ServerErrorKind::Config,
}
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum TlsKind {
Certificate,
PrivateKey,
}
impl std::fmt::Display for TlsKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TlsKind::Certificate => f.write_str("certificate"),
TlsKind::PrivateKey => f.write_str("private key"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn server_error_kind_matches_every_variant() {
assert_eq!(
ServerError::TlsLoad {
kind: TlsKind::Certificate,
path: PathBuf::from("x"),
reason: "x".to_owned(),
}
.kind(),
ServerErrorKind::TlsLoad
);
assert_eq!(
ServerError::ListenerAddress {
addr: "x".to_owned(),
reason: "x".to_owned(),
}
.kind(),
ServerErrorKind::ListenerAddress
);
assert_eq!(
ServerError::MiddlewareMissing {
path: PathBuf::from("x"),
}
.kind(),
ServerErrorKind::MiddlewareMissing
);
assert_eq!(
ServerError::MiddlewareCompile {
path: PathBuf::from("x"),
reason: "x".to_owned(),
}
.kind(),
ServerErrorKind::MiddlewareCompile
);
assert_eq!(
ServerError::Io(io::Error::other("x")).kind(),
ServerErrorKind::Io
);
assert_eq!(
ServerError::Config(apimock_config::ConfigError::Validation {
reason: "x".to_owned()
})
.kind(),
ServerErrorKind::Config
);
}
}