bgpkit_parser/parser/bmp/
error.rs

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