1use thiserror::Error;
7
8#[derive(Error, Debug)]
10pub enum BgpkitCommonsError {
11 #[error("Module '{module}' data not loaded. Call {load_method}() first")]
13 ModuleNotLoaded {
14 module: &'static str,
15 load_method: &'static str,
16 },
17
18 #[error(
20 "Module '{module}' not loaded with required configuration: {requirement}. Call {load_method}"
21 )]
22 ModuleNotConfigured {
23 module: &'static str,
24 requirement: &'static str,
25 load_method: &'static str,
26 },
27
28 #[error("Failed to load data from {data_source}: {details}")]
30 DataSourceError {
31 data_source: String,
32 details: String,
33 },
34
35 #[error("Invalid {data_type} format '{input}': {reason}")]
37 InvalidFormat {
38 data_type: &'static str,
39 input: String,
40 reason: String,
41 },
42
43 #[error(
45 "Feature '{feature}' is required but not enabled. Add '{feature}' to your Cargo.toml features"
46 )]
47 FeatureNotEnabled { feature: &'static str },
48
49 #[error("Network/IO error: {0}")]
51 NetworkError(#[from] std::io::Error),
52
53 #[cfg(feature = "serde_json")]
55 #[error("JSON parsing error: {0}")]
56 JsonError(#[from] serde_json::Error),
57
58 #[cfg(feature = "chrono")]
60 #[error("Date/time parsing error: {0}")]
61 ChronoError(#[from] chrono::ParseError),
62
63 #[cfg(feature = "ipnet")]
65 #[error("IP network parsing error: {0}")]
66 IpNetError(#[from] ipnet::AddrParseError),
67
68 #[cfg(feature = "oneio")]
70 #[error("OneIO error: {0}")]
71 OneIoError(#[from] oneio::OneIoError),
72
73 #[error("Parsing error: {0}")]
75 ParseIntError(#[from] std::num::ParseIntError),
76
77 #[error("Parsing error: {0}")]
79 ParseFloatError(#[from] std::num::ParseFloatError),
80
81 #[error("Internal error: {0}")]
83 Internal(String),
84}
85
86impl BgpkitCommonsError {
87 pub fn module_not_loaded(module: &'static str, load_method: &'static str) -> Self {
89 Self::ModuleNotLoaded {
90 module,
91 load_method,
92 }
93 }
94
95 pub fn module_not_configured(
97 module: &'static str,
98 requirement: &'static str,
99 load_method: &'static str,
100 ) -> Self {
101 Self::ModuleNotConfigured {
102 module,
103 requirement,
104 load_method,
105 }
106 }
107
108 pub fn data_source_error(source: impl Into<String>, details: impl Into<String>) -> Self {
110 Self::DataSourceError {
111 data_source: source.into(),
112 details: details.into(),
113 }
114 }
115
116 pub fn invalid_format(
118 data_type: &'static str,
119 input: impl Into<String>,
120 reason: impl Into<String>,
121 ) -> Self {
122 Self::InvalidFormat {
123 data_type,
124 input: input.into(),
125 reason: reason.into(),
126 }
127 }
128
129 pub fn feature_not_enabled(feature: &'static str) -> Self {
131 Self::FeatureNotEnabled { feature }
132 }
133}
134
135pub type Result<T> = std::result::Result<T, BgpkitCommonsError>;
137
138pub mod modules {
140 pub const ASINFO: &str = "asinfo";
141 pub const AS2REL: &str = "as2rel";
142 pub const BOGONS: &str = "bogons";
143 pub const COUNTRIES: &str = "countries";
144 pub const MRT_COLLECTORS: &str = "mrt_collectors";
145 pub const MRT_COLLECTOR_PEERS: &str = "mrt_collector_peers";
146 pub const RPKI: &str = "rpki";
147}
148
149pub mod load_methods {
151 pub const LOAD_ASINFO: &str = "load_asinfo";
152 pub const LOAD_ASINFO_CACHED: &str = "load_asinfo_cached";
153 pub const LOAD_AS2REL: &str = "load_as2rel";
154 pub const LOAD_BOGONS: &str = "load_bogons";
155 pub const LOAD_COUNTRIES: &str = "load_countries";
156 pub const LOAD_MRT_COLLECTORS: &str = "load_mrt_collectors";
157 pub const LOAD_MRT_COLLECTOR_PEERS: &str = "load_mrt_collector_peers";
158 pub const LOAD_RPKI: &str = "load_rpki";
159}
160
161pub mod data_sources {
163 pub const RIPE_NCC: &str = "RIPE NCC";
164 pub const CLOUDFLARE: &str = "Cloudflare";
165 pub const CAIDA: &str = "CAIDA";
166 pub const BGPKIT: &str = "BGPKIT";
167 pub const GEONAMES: &str = "GeoNames";
168 pub const IANA: &str = "IANA";
169 pub const ROUTEVIEWS: &str = "RouteViews";
170 pub const PEERINGDB: &str = "PeeringDB";
171 pub const APNIC: &str = "APNIC";
172 pub const IIJ_IHR: &str = "IIJ IHR";
173}