common/serde/
seq_block.rs1use bytes::{BufMut, Bytes, BytesMut};
25
26use super::DeserializeError;
27
28#[derive(Debug, Clone, PartialEq, Eq)]
36pub struct SeqBlock {
37 pub base_sequence: u64,
39 pub block_size: u64,
41}
42
43impl SeqBlock {
44 pub fn new(base_sequence: u64, block_size: u64) -> Self {
46 Self {
47 base_sequence,
48 block_size,
49 }
50 }
51
52 pub fn serialize(&self) -> Bytes {
56 let mut buf = BytesMut::with_capacity(16);
57 buf.put_u64(self.base_sequence);
58 buf.put_u64(self.block_size);
59 buf.freeze()
60 }
61
62 pub fn deserialize(data: &[u8]) -> Result<Self, DeserializeError> {
64 if data.len() < 16 {
65 return Err(DeserializeError {
66 message: format!(
67 "buffer too short for SeqBlock value: need 16 bytes, got {}",
68 data.len()
69 ),
70 });
71 }
72
73 let base_sequence = u64::from_be_bytes([
74 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
75 ]);
76 let block_size = u64::from_be_bytes([
77 data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
78 ]);
79
80 Ok(SeqBlock {
81 base_sequence,
82 block_size,
83 })
84 }
85
86 pub fn next_base(&self) -> u64 {
90 self.base_sequence + self.block_size
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn should_serialize_and_deserialize_seq_block() {
100 let value = SeqBlock::new(1000, 100);
102
103 let serialized = value.serialize();
105 let deserialized = SeqBlock::deserialize(&serialized).unwrap();
106
107 assert_eq!(deserialized, value);
109 assert_eq!(serialized.len(), 16);
110 }
111
112 #[test]
113 fn should_calculate_next_base() {
114 let value = SeqBlock::new(1000, 100);
116
117 let next = value.next_base();
119
120 assert_eq!(next, 1100);
122 }
123
124 #[test]
125 fn should_fail_deserialize_when_buffer_too_short() {
126 let data = vec![0u8; 15]; let result = SeqBlock::deserialize(&data);
131
132 assert!(result.is_err());
134 assert!(
135 result
136 .unwrap_err()
137 .message
138 .contains("buffer too short for SeqBlock value")
139 );
140 }
141
142 #[test]
143 fn should_serialize_in_big_endian() {
144 let value = SeqBlock::new(0x0102030405060708, 0x1112131415161718);
146
147 let serialized = value.serialize();
149
150 assert_eq!(
152 serialized.as_ref(),
153 &[
154 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, ]
157 );
158 }
159
160 #[test]
161 fn should_handle_zero_values() {
162 let value = SeqBlock::new(0, 0);
164
165 let serialized = value.serialize();
167 let deserialized = SeqBlock::deserialize(&serialized).unwrap();
168
169 assert_eq!(deserialized.base_sequence, 0);
171 assert_eq!(deserialized.block_size, 0);
172 assert_eq!(deserialized.next_base(), 0);
173 }
174
175 #[test]
176 fn should_handle_max_values() {
177 let value = SeqBlock::new(u64::MAX, u64::MAX);
179
180 let serialized = value.serialize();
182 let deserialized = SeqBlock::deserialize(&serialized).unwrap();
183
184 assert_eq!(deserialized.base_sequence, u64::MAX);
186 assert_eq!(deserialized.block_size, u64::MAX);
187 }
188}