nautilus_serialization/sbe/
primitives.rs1use super::{MAX_GROUP_SIZE, SbeCursor, SbeDecodeError};
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub struct GroupSizeEncoding {
23 pub block_length: u16,
25 pub num_in_group: u32,
27}
28
29impl GroupSizeEncoding {
30 pub const ENCODED_LENGTH: usize = 6;
32
33 pub fn decode(buf: &[u8]) -> Result<Self, SbeDecodeError> {
40 if buf.len() < Self::ENCODED_LENGTH {
41 return Err(SbeDecodeError::BufferTooShort {
42 expected: Self::ENCODED_LENGTH,
43 actual: buf.len(),
44 });
45 }
46
47 let num_in_group = u32::from_le_bytes([buf[2], buf[3], buf[4], buf[5]]);
48 if num_in_group > MAX_GROUP_SIZE {
49 return Err(SbeDecodeError::GroupSizeTooLarge {
50 count: num_in_group,
51 max: MAX_GROUP_SIZE,
52 });
53 }
54
55 Ok(Self {
56 block_length: u16::from_le_bytes([buf[0], buf[1]]),
57 num_in_group,
58 })
59 }
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub struct GroupSize16Encoding {
65 pub block_length: u16,
67 pub num_in_group: u16,
69}
70
71impl GroupSize16Encoding {
72 pub const ENCODED_LENGTH: usize = 4;
74
75 pub fn decode(buf: &[u8]) -> Result<Self, SbeDecodeError> {
82 if buf.len() < Self::ENCODED_LENGTH {
83 return Err(SbeDecodeError::BufferTooShort {
84 expected: Self::ENCODED_LENGTH,
85 actual: buf.len(),
86 });
87 }
88
89 let num_in_group = u16::from_le_bytes([buf[2], buf[3]]);
90 if u32::from(num_in_group) > MAX_GROUP_SIZE {
91 return Err(SbeDecodeError::GroupSizeTooLarge {
92 count: u32::from(num_in_group),
93 max: MAX_GROUP_SIZE,
94 });
95 }
96
97 Ok(Self {
98 block_length: u16::from_le_bytes([buf[0], buf[1]]),
99 num_in_group,
100 })
101 }
102}
103
104pub fn decode_var_string8(buf: &[u8]) -> Result<(&str, usize), SbeDecodeError> {
113 let mut cursor = SbeCursor::new(buf);
114 let value = cursor.read_var_string8_ref()?;
115 Ok((value, cursor.pos()))
116}
117
118#[cfg(test)]
119mod tests {
120 use rstest::rstest;
121
122 use super::*;
123
124 #[rstest]
125 fn test_group_size_decode_too_short() {
126 let err = GroupSizeEncoding::decode(&[0, 0, 0]).unwrap_err();
127 assert_eq!(
128 err,
129 SbeDecodeError::BufferTooShort {
130 expected: 6,
131 actual: 3
132 }
133 );
134 }
135
136 #[rstest]
137 fn test_group_size_decode_too_large() {
138 let mut buf = [0u8; GroupSizeEncoding::ENCODED_LENGTH];
139 buf[2..6].copy_from_slice(&(MAX_GROUP_SIZE + 1).to_le_bytes());
140 let err = GroupSizeEncoding::decode(&buf).unwrap_err();
141 assert_eq!(
142 err,
143 SbeDecodeError::GroupSizeTooLarge {
144 count: MAX_GROUP_SIZE + 1,
145 max: MAX_GROUP_SIZE
146 }
147 );
148 }
149
150 #[rstest]
151 fn test_group_size_16_decode_too_large() {
152 let mut buf = [0u8; GroupSize16Encoding::ENCODED_LENGTH];
153 buf[2..4].copy_from_slice(&(MAX_GROUP_SIZE as u16 + 1).to_le_bytes());
154 let err = GroupSize16Encoding::decode(&buf).unwrap_err();
155 assert_eq!(
156 err,
157 SbeDecodeError::GroupSizeTooLarge {
158 count: MAX_GROUP_SIZE + 1,
159 max: MAX_GROUP_SIZE
160 }
161 );
162 }
163
164 #[rstest]
165 fn test_decode_var_string8_valid() {
166 let buf = [5u8, b'H', b'E', b'L', b'L', b'O'];
167 let (s, consumed) = decode_var_string8(&buf).unwrap();
168 assert_eq!(s, "HELLO");
169 assert_eq!(consumed, 6);
170 }
171
172 #[rstest]
173 fn test_decode_var_string8_invalid_utf8() {
174 let buf = [2u8, 0xFF, 0xFF];
175 let err = decode_var_string8(&buf).unwrap_err();
176 assert_eq!(err, SbeDecodeError::InvalidUtf8);
177 }
178
179 #[rstest]
180 #[case(0)]
181 #[case(1)]
182 #[case(MAX_GROUP_SIZE)]
183 fn test_group_headers_preserve_fields(#[case] count: u32) {
184 let block_length = 0x1234_u16;
185 let mut wide = block_length.to_le_bytes().to_vec();
186 wide.extend_from_slice(&count.to_le_bytes());
187 let mut compact = block_length.to_le_bytes().to_vec();
188 compact.extend_from_slice(&u16::try_from(count).unwrap().to_le_bytes());
189
190 assert_eq!(
191 GroupSizeEncoding::decode(&wide),
192 Ok(GroupSizeEncoding {
193 block_length,
194 num_in_group: count,
195 })
196 );
197 assert_eq!(
198 GroupSize16Encoding::decode(&compact),
199 Ok(GroupSize16Encoding {
200 block_length,
201 num_in_group: count as u16,
202 })
203 );
204 }
205
206 #[rstest]
207 #[case(0)]
208 #[case(1)]
209 #[case(2)]
210 #[case(3)]
211 fn test_group_size_16_decode_too_short(#[case] len: usize) {
212 assert_eq!(
213 GroupSize16Encoding::decode(&[0; 4][..len]),
214 Err(SbeDecodeError::BufferTooShort {
215 expected: 4,
216 actual: len
217 })
218 );
219 }
220}