nautilus_serialization/sbe/
error.rs1use std::{error::Error, fmt::Display};
19
20pub const MAX_GROUP_SIZE: u32 = 10_000;
22
23#[derive(Debug, Clone, PartialEq, Eq)]
25pub enum SbeEncodeError {
26 InvalidGroupSize {
28 group: &'static str,
30 count: usize,
32 expected: usize,
34 },
35 StringTooLong {
37 field: &'static str,
39 len: usize,
41 max: usize,
43 },
44 GroupSizeTooLarge {
46 group: &'static str,
48 count: usize,
50 max: u32,
52 },
53 NumericOverflow {
55 field: &'static str,
57 },
58 ReservedValue {
60 field: &'static str,
62 },
63}
64
65impl Display for SbeEncodeError {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 Self::InvalidGroupSize {
69 group,
70 count,
71 expected,
72 } => {
73 write!(
74 f,
75 "Group `{group}` requires {expected} entries, found {count}"
76 )
77 }
78
79 Self::StringTooLong { field, len, max } => {
80 write!(
81 f,
82 "String field `{field}` length {len} exceeds maximum {max}"
83 )
84 }
85 Self::GroupSizeTooLarge { group, count, max } => {
86 write!(f, "Group `{group}` size {count} exceeds maximum {max}")
87 }
88 Self::NumericOverflow { field } => {
89 write!(f, "Numeric value overflows encoded field {field}")
90 }
91 Self::ReservedValue { field } => {
92 write!(f, "Value for {field} is reserved by the wire encoding")
93 }
94 }
95 }
96}
97
98impl Error for SbeEncodeError {}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
102pub enum SbeDecodeError {
103 BufferTooShort {
105 expected: usize,
107 actual: usize,
109 },
110 SchemaMismatch {
112 expected: u16,
114 actual: u16,
116 },
117 VersionMismatch {
119 expected: u16,
121 actual: u16,
123 },
124 UnknownTemplateId(u16),
126 GroupSizeTooLarge {
128 count: u32,
130 max: u32,
132 },
133 InvalidBlockLength {
135 expected: u16,
137 actual: u16,
139 },
140 InvalidUtf8,
142 InvalidEnumValue {
144 type_name: &'static str,
146 value: u16,
148 },
149 NumericOverflow {
151 type_name: &'static str,
153 },
154 InvalidValue {
156 field: &'static str,
158 },
159}
160
161impl Display for SbeDecodeError {
162 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163 match self {
164 Self::BufferTooShort { expected, actual } => {
165 write!(
166 f,
167 "Buffer too short: expected {expected} bytes, was {actual}"
168 )
169 }
170 Self::SchemaMismatch { expected, actual } => {
171 write!(f, "Schema ID mismatch: expected {expected}, was {actual}")
172 }
173 Self::VersionMismatch { expected, actual } => {
174 write!(
175 f,
176 "Schema version mismatch: expected {expected}, was {actual}"
177 )
178 }
179 Self::UnknownTemplateId(id) => write!(f, "Unknown template ID: {id}"),
180 Self::GroupSizeTooLarge { count, max } => {
181 write!(f, "Group size {count} exceeds maximum {max}")
182 }
183 Self::InvalidBlockLength { expected, actual } => {
184 write!(f, "Invalid block length: expected {expected}, was {actual}")
185 }
186 Self::InvalidUtf8 => write!(f, "Invalid UTF-8 in string field"),
187 Self::InvalidEnumValue { type_name, value } => {
188 write!(f, "Invalid enum value {value} for {type_name}")
189 }
190 Self::NumericOverflow { type_name } => {
191 write!(f, "Numeric value overflows target type {type_name}")
192 }
193 Self::InvalidValue { field } => write!(f, "Invalid value for {field}"),
194 }
195 }
196}
197
198impl Error for SbeDecodeError {}
199
200#[cfg(test)]
201mod tests {
202 use rstest::rstest;
203
204 use super::*;
205
206 #[rstest]
207 fn test_string_too_long_display() {
208 let err = SbeEncodeError::StringTooLong {
209 field: "symbol",
210 len: 300,
211 max: 65535,
212 };
213 assert_eq!(
214 err.to_string(),
215 "String field `symbol` length 300 exceeds maximum 65535"
216 );
217 }
218
219 #[rstest]
220 fn test_numeric_overflow_display() {
221 let err = SbeEncodeError::NumericOverflow {
222 field: "BarSpecification.step",
223 };
224 assert_eq!(
225 err.to_string(),
226 "Numeric value overflows encoded field BarSpecification.step"
227 );
228 }
229
230 #[rstest]
231 fn test_reserved_value_display() {
232 let err = SbeEncodeError::ReservedValue {
233 field: "FundingRateUpdate.interval",
234 };
235 assert_eq!(
236 err.to_string(),
237 "Value for FundingRateUpdate.interval is reserved by the wire encoding"
238 );
239 }
240
241 #[rstest]
242 fn test_buffer_too_short_display() {
243 let err = SbeDecodeError::BufferTooShort {
244 expected: 100,
245 actual: 50,
246 };
247 assert_eq!(
248 err.to_string(),
249 "Buffer too short: expected 100 bytes, was 50"
250 );
251 }
252
253 #[rstest]
254 fn test_schema_mismatch_display() {
255 let err = SbeDecodeError::SchemaMismatch {
256 expected: 3,
257 actual: 1,
258 };
259 assert_eq!(err.to_string(), "Schema ID mismatch: expected 3, was 1");
260 }
261
262 #[rstest]
263 fn test_group_size_too_large_display() {
264 let err = SbeDecodeError::GroupSizeTooLarge {
265 count: 50000,
266 max: 10000,
267 };
268 assert_eq!(err.to_string(), "Group size 50000 exceeds maximum 10000");
269 }
270
271 #[rstest]
272 fn test_error_equality() {
273 let err1 = SbeDecodeError::InvalidUtf8;
274 let err2 = SbeDecodeError::InvalidUtf8;
275 assert_eq!(err1, err2);
276 }
277
278 #[rstest]
279 fn test_invalid_enum_value_display() {
280 let err = SbeDecodeError::InvalidEnumValue {
281 type_name: "OrderSide",
282 value: 99,
283 };
284 assert_eq!(err.to_string(), "Invalid enum value 99 for OrderSide");
285 }
286}