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 StringTooLong {
28 field: &'static str,
30 len: usize,
32 max: usize,
34 },
35 GroupSizeTooLarge {
37 group: &'static str,
39 count: usize,
41 max: u32,
43 },
44 NumericOverflow {
46 field: &'static str,
48 },
49 ReservedValue {
51 field: &'static str,
53 },
54}
55
56impl Display for SbeEncodeError {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 match self {
59 Self::StringTooLong { field, len, max } => {
60 write!(
61 f,
62 "String field `{field}` length {len} exceeds maximum {max}"
63 )
64 }
65 Self::GroupSizeTooLarge { group, count, max } => {
66 write!(f, "Group `{group}` size {count} exceeds maximum {max}")
67 }
68 Self::NumericOverflow { field } => {
69 write!(f, "Numeric value overflows encoded field {field}")
70 }
71 Self::ReservedValue { field } => {
72 write!(f, "Value for {field} is reserved by the wire encoding")
73 }
74 }
75 }
76}
77
78impl Error for SbeEncodeError {}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
82pub enum SbeDecodeError {
83 BufferTooShort {
85 expected: usize,
87 actual: usize,
89 },
90 SchemaMismatch {
92 expected: u16,
94 actual: u16,
96 },
97 VersionMismatch {
99 expected: u16,
101 actual: u16,
103 },
104 UnknownTemplateId(u16),
106 GroupSizeTooLarge {
108 count: u32,
110 max: u32,
112 },
113 InvalidBlockLength {
115 expected: u16,
117 actual: u16,
119 },
120 InvalidUtf8,
122 InvalidEnumValue {
124 type_name: &'static str,
126 value: u16,
128 },
129 NumericOverflow {
131 type_name: &'static str,
133 },
134 InvalidValue {
136 field: &'static str,
138 },
139}
140
141impl Display for SbeDecodeError {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 match self {
144 Self::BufferTooShort { expected, actual } => {
145 write!(
146 f,
147 "Buffer too short: expected {expected} bytes, was {actual}"
148 )
149 }
150 Self::SchemaMismatch { expected, actual } => {
151 write!(f, "Schema ID mismatch: expected {expected}, was {actual}")
152 }
153 Self::VersionMismatch { expected, actual } => {
154 write!(
155 f,
156 "Schema version mismatch: expected {expected}, was {actual}"
157 )
158 }
159 Self::UnknownTemplateId(id) => write!(f, "Unknown template ID: {id}"),
160 Self::GroupSizeTooLarge { count, max } => {
161 write!(f, "Group size {count} exceeds maximum {max}")
162 }
163 Self::InvalidBlockLength { expected, actual } => {
164 write!(f, "Invalid block length: expected {expected}, was {actual}")
165 }
166 Self::InvalidUtf8 => write!(f, "Invalid UTF-8 in string field"),
167 Self::InvalidEnumValue { type_name, value } => {
168 write!(f, "Invalid enum value {value} for {type_name}")
169 }
170 Self::NumericOverflow { type_name } => {
171 write!(f, "Numeric value overflows target type {type_name}")
172 }
173 Self::InvalidValue { field } => write!(f, "Invalid value for {field}"),
174 }
175 }
176}
177
178impl Error for SbeDecodeError {}
179
180#[cfg(test)]
181mod tests {
182 use rstest::rstest;
183
184 use super::*;
185
186 #[rstest]
187 fn test_string_too_long_display() {
188 let err = SbeEncodeError::StringTooLong {
189 field: "symbol",
190 len: 300,
191 max: 65535,
192 };
193 assert_eq!(
194 err.to_string(),
195 "String field `symbol` length 300 exceeds maximum 65535"
196 );
197 }
198
199 #[rstest]
200 fn test_numeric_overflow_display() {
201 let err = SbeEncodeError::NumericOverflow {
202 field: "BarSpecification.step",
203 };
204 assert_eq!(
205 err.to_string(),
206 "Numeric value overflows encoded field BarSpecification.step"
207 );
208 }
209
210 #[rstest]
211 fn test_reserved_value_display() {
212 let err = SbeEncodeError::ReservedValue {
213 field: "FundingRateUpdate.interval",
214 };
215 assert_eq!(
216 err.to_string(),
217 "Value for FundingRateUpdate.interval is reserved by the wire encoding"
218 );
219 }
220
221 #[rstest]
222 fn test_buffer_too_short_display() {
223 let err = SbeDecodeError::BufferTooShort {
224 expected: 100,
225 actual: 50,
226 };
227 assert_eq!(
228 err.to_string(),
229 "Buffer too short: expected 100 bytes, was 50"
230 );
231 }
232
233 #[rstest]
234 fn test_schema_mismatch_display() {
235 let err = SbeDecodeError::SchemaMismatch {
236 expected: 3,
237 actual: 1,
238 };
239 assert_eq!(err.to_string(), "Schema ID mismatch: expected 3, was 1");
240 }
241
242 #[rstest]
243 fn test_group_size_too_large_display() {
244 let err = SbeDecodeError::GroupSizeTooLarge {
245 count: 50000,
246 max: 10000,
247 };
248 assert_eq!(err.to_string(), "Group size 50000 exceeds maximum 10000");
249 }
250
251 #[rstest]
252 fn test_error_equality() {
253 let err1 = SbeDecodeError::InvalidUtf8;
254 let err2 = SbeDecodeError::InvalidUtf8;
255 assert_eq!(err1, err2);
256 }
257
258 #[rstest]
259 fn test_invalid_enum_value_display() {
260 let err = SbeDecodeError::InvalidEnumValue {
261 type_name: "OrderSide",
262 value: 99,
263 };
264 assert_eq!(err.to_string(), "Invalid enum value 99 for OrderSide");
265 }
266}