bgpkit_parser/parser/bmp/
error.rs1use crate::bmp::messages::headers::BmpPeerType;
2use crate::bmp::messages::peer_down_notification::PeerDownReason;
3use crate::bmp::messages::route_mirroring::RouteMirroringInfo;
4use crate::bmp::messages::termination_message::{TerminationReason, TerminationTlvType};
5use crate::bmp::messages::BmpMsgType;
6use crate::ParserError;
7use num_enum::TryFromPrimitiveError;
8use std::error::Error;
9use std::fmt::{Display, Formatter};
10
11#[derive(Debug, PartialEq, Clone, Eq)]
12#[non_exhaustive]
13pub enum ParserBmpError {
14 InvalidOpenBmpHeader,
15 UnsupportedOpenBmpMessage,
16 UnknownTlvType,
17 UnknownTlvValue,
18 CorruptedBmpMessage,
19 CorruptedBgpMessage(String),
20 TruncatedBmpMessage,
21 IoError {
25 kind: std::io::ErrorKind,
26 message: String,
27 },
28 UnknownMessageType(u8),
30}
31
32impl Display for ParserBmpError {
33 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
34 match self {
35 ParserBmpError::InvalidOpenBmpHeader => {
36 write!(f, "Invalid OpenBMP header")
37 }
38 ParserBmpError::UnsupportedOpenBmpMessage => {
39 write!(f, "Unsupported OpenBMP message")
40 }
41 ParserBmpError::CorruptedBmpMessage => {
42 write!(f, "Corrupted BMP message")
43 }
44 ParserBmpError::TruncatedBmpMessage => {
45 write!(f, "Truncated BMP message")
46 }
47 ParserBmpError::UnknownTlvType => {
48 write!(f, "Unknown TLV type")
49 }
50 ParserBmpError::UnknownTlvValue => {
51 write!(f, "Unknown TLV value")
52 }
53 ParserBmpError::CorruptedBgpMessage(s) => {
54 write!(f, "Corrupted BGP message: {}", s)
55 }
56 ParserBmpError::IoError { kind, message } => {
57 write!(f, "BMP read error ({:?}): {}", kind, message)
58 }
59 ParserBmpError::UnknownMessageType(value) => {
60 write!(f, "Unknown BMP message type: {}", value)
61 }
62 }
63 }
64}
65
66impl Error for ParserBmpError {}
67
68impl From<std::io::Error> for ParserBmpError {
69 fn from(e: std::io::Error) -> Self {
70 ParserBmpError::IoError {
71 kind: e.kind(),
72 message: e.to_string(),
73 }
74 }
75}
76
77impl From<ParserError> for ParserBmpError {
78 fn from(e: ParserError) -> Self {
79 ParserBmpError::CorruptedBgpMessage(e.to_string())
80 }
81}
82
83impl From<TryFromPrimitiveError<BmpMsgType>> for ParserBmpError {
84 fn from(e: TryFromPrimitiveError<BmpMsgType>) -> Self {
85 ParserBmpError::UnknownMessageType(e.number)
86 }
87}
88
89impl From<TryFromPrimitiveError<BmpPeerType>> for ParserBmpError {
90 fn from(_: TryFromPrimitiveError<BmpPeerType>) -> Self {
91 ParserBmpError::CorruptedBmpMessage
92 }
93}
94
95impl From<TryFromPrimitiveError<RouteMirroringInfo>> for ParserBmpError {
96 fn from(_: TryFromPrimitiveError<RouteMirroringInfo>) -> Self {
97 ParserBmpError::CorruptedBmpMessage
98 }
99}
100
101impl From<TryFromPrimitiveError<TerminationTlvType>> for ParserBmpError {
102 fn from(_: TryFromPrimitiveError<TerminationTlvType>) -> Self {
103 ParserBmpError::UnknownTlvType
104 }
105}
106
107impl From<TryFromPrimitiveError<TerminationReason>> for ParserBmpError {
108 fn from(_: TryFromPrimitiveError<TerminationReason>) -> Self {
109 ParserBmpError::UnknownTlvValue
110 }
111}
112
113impl From<TryFromPrimitiveError<PeerDownReason>> for ParserBmpError {
114 fn from(_: TryFromPrimitiveError<PeerDownReason>) -> Self {
115 ParserBmpError::UnknownTlvValue
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_parser_error_display() {
125 assert_eq!(
126 ParserBmpError::InvalidOpenBmpHeader.to_string(),
127 "Invalid OpenBMP header"
128 );
129 assert_eq!(
130 ParserBmpError::UnsupportedOpenBmpMessage.to_string(),
131 "Unsupported OpenBMP message"
132 );
133 assert_eq!(
134 ParserBmpError::CorruptedBmpMessage.to_string(),
135 "Corrupted BMP message"
136 );
137 assert_eq!(
138 ParserBmpError::CorruptedBgpMessage("test".to_string()).to_string(),
139 "Corrupted BGP message: test"
140 );
141 assert_eq!(
142 ParserBmpError::TruncatedBmpMessage.to_string(),
143 "Truncated BMP message"
144 );
145 assert_eq!(
146 ParserBmpError::UnknownTlvType.to_string(),
147 "Unknown TLV type"
148 );
149 assert_eq!(
150 ParserBmpError::UnknownTlvValue.to_string(),
151 "Unknown TLV value"
152 );
153 assert_eq!(
154 ParserBmpError::IoError {
155 kind: std::io::ErrorKind::UnexpectedEof,
156 message: "unexpected eof".to_string(),
157 }
158 .to_string(),
159 "BMP read error (UnexpectedEof): unexpected eof"
160 );
161 assert_eq!(
162 ParserBmpError::UnknownMessageType(7).to_string(),
163 "Unknown BMP message type: 7"
164 );
165 }
166
167 #[test]
168 fn test_error_conversions() {
169 assert_eq!(
170 ParserBmpError::from(std::io::Error::other("test")),
171 ParserBmpError::IoError {
172 kind: std::io::ErrorKind::Other,
173 message: "test".to_string(),
174 }
175 );
176 assert_eq!(
177 ParserBmpError::from(ParserError::ParseError("test".to_string())),
178 ParserBmpError::CorruptedBgpMessage("Error: test".to_string())
179 );
180 assert_eq!(
181 ParserBmpError::from(TryFromPrimitiveError::<BmpMsgType>::new(0)),
182 ParserBmpError::UnknownMessageType(0)
183 );
184 assert_eq!(
185 ParserBmpError::from(TryFromPrimitiveError::<BmpPeerType>::new(0)),
186 ParserBmpError::CorruptedBmpMessage
187 );
188 assert_eq!(
189 ParserBmpError::from(TryFromPrimitiveError::<RouteMirroringInfo>::new(0)),
190 ParserBmpError::CorruptedBmpMessage
191 );
192 assert_eq!(
193 ParserBmpError::from(TryFromPrimitiveError::<TerminationTlvType>::new(0)),
194 ParserBmpError::UnknownTlvType
195 );
196 assert_eq!(
197 ParserBmpError::from(TryFromPrimitiveError::<TerminationReason>::new(0)),
198 ParserBmpError::UnknownTlvValue
199 );
200 assert_eq!(
201 ParserBmpError::from(TryFromPrimitiveError::<PeerDownReason>::new(0)),
202 ParserBmpError::UnknownTlvValue
203 );
204 }
205}