use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("Failed to read config file '{}': {source}", path.display())]
FileRead {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("Failed to parse TOML config: {0}")]
TomlParse(#[from] toml::de::Error),
#[error("Failed to write config file '{}': {source}", path.display())]
FileWrite {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("Missing required field: {field}. {hint}")]
MissingRequired {
field: &'static str,
hint: &'static str,
},
#[error("Invalid URL '{url}': {reason}")]
InvalidUrl {
url: String,
reason: String,
},
#[error("Invalid regex pattern '{pattern}': {source}")]
InvalidRegex {
pattern: String,
#[source]
source: regex::Error,
},
#[error("Invalid duration for {field}: {reason}")]
InvalidDuration {
field: &'static str,
reason: String,
},
#[error("Invalid retry configuration: {0}")]
InvalidRetry(String),
#[error("Invalid HTTP method '{0}'")]
InvalidMethod(String),
#[error("Invalid IP version '{value}': expected ipv4, ipv6, or both")]
InvalidIpVersion {
value: String,
},
#[error("Invalid adapter kind '{value}': expected ethernet, wireless, virtual, or loopback")]
InvalidAdapterKind {
value: String,
},
#[error("Invalid change kind '{value}': expected added, removed, or both")]
InvalidChangeKind {
value: String,
},
#[error("Invalid header format '{value}': expected 'Key=Value' or 'Key: Value'")]
InvalidHeader {
value: String,
},
#[error("Invalid header name '{name}': {reason}")]
InvalidHeaderName {
name: String,
reason: String,
},
#[error("Invalid header value for '{name}': {reason}")]
InvalidHeaderValue {
name: String,
reason: String,
},
#[error("Invalid body template: {reason}")]
InvalidTemplate {
reason: String,
},
}
pub mod field {
pub const URL: &str = "url";
pub const IP_VERSION: &str = "ip_version";
}
impl ConfigError {
#[must_use]
pub const fn missing(field: &'static str, hint: &'static str) -> Self {
Self::MissingRequired { field, hint }
}
}