use std::io;
use std::net::AddrParseError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("configuration error")]
Config(#[from] ConfigError),
#[error("network error")]
Network(#[from] NetworkError),
#[error("DNS protocol error")]
Protocol(#[from] hickory_proto::ProtoError),
#[error("resolver error: {0}")]
Resolver(String),
#[error("I/O error")]
Io(#[from] io::Error),
#[error("metrics error")]
Metrics(#[from] metrics_exporter_prometheus::BuildError),
}
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("failed to read config file")]
ReadFile(#[source] io::Error),
#[error("failed to parse config")]
Parse(#[source] toml::de::Error),
#[error("invalid upstream resolver address")]
InvalidResolver(#[source] AddrParseError),
#[error("validation failed")]
Validation(#[from] ValidationError),
}
#[derive(Debug, Error)]
pub enum ValidationError {
#[error("cache_ttl_seconds must be greater than 0")]
ZeroCacheTtl,
#[error("buffer_pool_size must be greater than 0")]
ZeroBufferPoolSize,
#[error("channel_capacity must be greater than 0")]
ZeroChannelCapacity,
#[error("arp_spoof.spoof_interval_secs must be greater than 0")]
ZeroSpoofInterval,
#[error("blocklist pattern cannot be empty")]
EmptyBlocklistPattern,
#[error("invalid wildcard pattern: {pattern:?}")]
InvalidWildcardPattern { pattern: String },
#[error("blocklist source name cannot be empty")]
EmptyBlocklistSourceName,
#[error("duplicate blocklist source name: {name:?}")]
DuplicateBlocklistSourceName { name: String },
#[error("blocklist source {name:?} has empty file path")]
EmptyBlocklistSourcePath { name: String },
#[error("blocklist source {name:?} has empty URL")]
EmptyBlocklistSourceUrl { name: String },
#[error(
"blocklist source {name:?} has invalid URL (must start with http:// or https://): {url:?}"
)]
InvalidBlocklistSourceUrl { name: String, url: String },
}
#[derive(Debug, Error)]
pub enum NetworkError {
#[error("no suitable network interface found")]
NoInterface,
#[error("failed to open datalink channel: {0}")]
ChannelOpen(String),
#[error("unsupported channel type")]
UnsupportedChannel,
#[error("failed to send packet: {0}")]
SendFailed(String),
#[error("packet construction failed: {0}")]
PacketConstruction(String),
}
pub type Result<T> = std::result::Result<T, Error>;