use thiserror::Error;
#[derive(Error, Debug)]
pub enum BgpkitCommonsError {
#[error("Module '{module}' data not loaded. Call {load_method}() first")]
ModuleNotLoaded {
module: &'static str,
load_method: &'static str,
},
#[error(
"Module '{module}' not loaded with required configuration: {requirement}. Call {load_method}"
)]
ModuleNotConfigured {
module: &'static str,
requirement: &'static str,
load_method: &'static str,
},
#[error("Failed to load data from {data_source}: {details}")]
DataSourceError {
data_source: String,
details: String,
},
#[error("Invalid {data_type} format '{input}': {reason}")]
InvalidFormat {
data_type: &'static str,
input: String,
reason: String,
},
#[error(
"Feature '{feature}' is required but not enabled. Add '{feature}' to your Cargo.toml features"
)]
FeatureNotEnabled { feature: &'static str },
#[error("Network/IO error: {0}")]
NetworkError(#[from] std::io::Error),
#[cfg(feature = "serde_json")]
#[error("JSON parsing error: {0}")]
JsonError(#[from] serde_json::Error),
#[cfg(feature = "chrono")]
#[error("Date/time parsing error: {0}")]
ChronoError(#[from] chrono::ParseError),
#[cfg(feature = "ipnet")]
#[error("IP network parsing error: {0}")]
IpNetError(#[from] ipnet::AddrParseError),
#[cfg(feature = "oneio")]
#[error("OneIO error: {0}")]
OneIoError(#[from] oneio::OneIoError),
#[error("Parsing error: {0}")]
ParseIntError(#[from] std::num::ParseIntError),
#[error("Parsing error: {0}")]
ParseFloatError(#[from] std::num::ParseFloatError),
#[error("Internal error: {0}")]
Internal(String),
}
impl BgpkitCommonsError {
pub fn module_not_loaded(module: &'static str, load_method: &'static str) -> Self {
Self::ModuleNotLoaded {
module,
load_method,
}
}
pub fn module_not_configured(
module: &'static str,
requirement: &'static str,
load_method: &'static str,
) -> Self {
Self::ModuleNotConfigured {
module,
requirement,
load_method,
}
}
pub fn data_source_error(source: impl Into<String>, details: impl Into<String>) -> Self {
Self::DataSourceError {
data_source: source.into(),
details: details.into(),
}
}
pub fn invalid_format(
data_type: &'static str,
input: impl Into<String>,
reason: impl Into<String>,
) -> Self {
Self::InvalidFormat {
data_type,
input: input.into(),
reason: reason.into(),
}
}
pub fn feature_not_enabled(feature: &'static str) -> Self {
Self::FeatureNotEnabled { feature }
}
}
pub type Result<T> = std::result::Result<T, BgpkitCommonsError>;
pub mod modules {
pub const ASINFO: &str = "asinfo";
pub const AS2REL: &str = "as2rel";
pub const BOGONS: &str = "bogons";
pub const COUNTRIES: &str = "countries";
pub const MRT_COLLECTORS: &str = "mrt_collectors";
pub const MRT_COLLECTOR_PEERS: &str = "mrt_collector_peers";
pub const RPKI: &str = "rpki";
}
pub mod load_methods {
pub const LOAD_ASINFO: &str = "load_asinfo";
pub const LOAD_ASINFO_CACHED: &str = "load_asinfo_cached";
pub const LOAD_AS2REL: &str = "load_as2rel";
pub const LOAD_BOGONS: &str = "load_bogons";
pub const LOAD_COUNTRIES: &str = "load_countries";
pub const LOAD_MRT_COLLECTORS: &str = "load_mrt_collectors";
pub const LOAD_MRT_COLLECTOR_PEERS: &str = "load_mrt_collector_peers";
pub const LOAD_RPKI: &str = "load_rpki";
}
pub mod data_sources {
pub const RIPE_NCC: &str = "RIPE NCC";
pub const CLOUDFLARE: &str = "Cloudflare";
pub const CAIDA: &str = "CAIDA";
pub const BGPKIT: &str = "BGPKIT";
pub const GEONAMES: &str = "GeoNames";
pub const IANA: &str = "IANA";
pub const ROUTEVIEWS: &str = "RouteViews";
pub const PEERINGDB: &str = "PeeringDB";
pub const APNIC: &str = "APNIC";
pub const IIJ_IHR: &str = "IIJ IHR";
}