1use core::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum WireError {
11 WriteOverflow {
13 needed: usize,
15 available: usize,
17 },
18 UnexpectedEof {
20 needed: usize,
22 offset: usize,
24 },
25 InvalidMagic {
27 found: [u8; 4],
29 },
30 UnknownSubmessageId {
32 id: u8,
34 },
35 InvalidLocatorKind {
37 kind: i32,
39 },
40 ValueOutOfRange {
42 message: &'static str,
44 },
45 UnsupportedEncapsulation {
48 kind: [u8; 2],
50 },
51 UnsupportedFeature {
54 what: &'static str,
56 },
57}
58
59impl fmt::Display for WireError {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 match self {
62 Self::WriteOverflow { needed, available } => {
63 write!(
64 f,
65 "RTPS write overflow: needed {needed}, available {available}"
66 )
67 }
68 Self::UnexpectedEof { needed, offset } => {
69 write!(f, "RTPS unexpected EOF: needed {needed} at offset {offset}")
70 }
71 Self::InvalidMagic { found } => {
72 write!(f, "RTPS invalid magic: expected b\"RTPS\", got {found:?}")
73 }
74 Self::UnknownSubmessageId { id } => {
75 write!(f, "RTPS unknown submessage id 0x{id:02x}")
76 }
77 Self::InvalidLocatorKind { kind } => {
78 write!(f, "RTPS invalid locator kind {kind}")
79 }
80 Self::ValueOutOfRange { message } => write!(f, "RTPS value out of range: {message}"),
81 Self::UnsupportedEncapsulation { kind } => {
82 write!(
83 f,
84 "RTPS unsupported encapsulation kind 0x{:02x}{:02x}",
85 kind[0], kind[1]
86 )
87 }
88 Self::UnsupportedFeature { what } => {
89 write!(f, "RTPS unsupported feature: {what}")
90 }
91 }
92 }
93}
94
95#[cfg(feature = "std")]
96impl std::error::Error for WireError {}
97
98#[cfg(test)]
99mod tests {
100 #![allow(clippy::expect_used)]
101 use super::*;
102
103 #[cfg(feature = "alloc")]
104 extern crate alloc;
105 #[cfg(feature = "alloc")]
106 use alloc::format;
107
108 #[cfg(feature = "alloc")]
109 #[test]
110 fn write_overflow_display() {
111 let e = WireError::WriteOverflow {
112 needed: 16,
113 available: 4,
114 };
115 let s = format!("{e}");
116 assert!(s.contains("16"));
117 assert!(s.contains("4"));
118 }
119
120 #[cfg(feature = "alloc")]
121 #[test]
122 fn invalid_magic_display() {
123 let e = WireError::InvalidMagic {
124 found: [b'X', b'X', b'X', b'X'],
125 };
126 let s = format!("{e}");
127 assert!(s.contains("RTPS"));
128 }
129
130 #[cfg(feature = "alloc")]
131 #[test]
132 fn unknown_submessage_id_display_uses_hex() {
133 let e = WireError::UnknownSubmessageId { id: 0x42 };
134 let s = format!("{e}");
135 assert!(s.contains("42"));
136 }
137
138 #[cfg(feature = "alloc")]
139 #[test]
140 fn invalid_locator_kind_display() {
141 let e = WireError::InvalidLocatorKind { kind: 99 };
142 assert!(format!("{e}").contains("99"));
143 }
144
145 #[cfg(feature = "alloc")]
146 #[test]
147 fn value_out_of_range_display() {
148 let e = WireError::ValueOutOfRange { message: "too big" };
149 assert!(format!("{e}").contains("too big"));
150 }
151
152 #[cfg(feature = "alloc")]
153 #[test]
154 fn unexpected_eof_display() {
155 let e = WireError::UnexpectedEof {
156 needed: 8,
157 offset: 12,
158 };
159 let s = format!("{e}");
160 assert!(s.contains("8"));
161 assert!(s.contains("12"));
162 }
163}