1use crate::{binary_put_uvariant_to_bufmut, binary_put_uvariant_to_vec, binary_uvarint};
2use alloc::vec::Vec;
3use bytes::{BufMut, Bytes, BytesMut};
4
5pub const MAX_HEADER_SIZE: usize = 21;
8
9#[derive(Copy, Clone, Eq, PartialEq, Debug)]
11#[repr(C)]
12pub struct Header {
13 meta: u8,
14 user_meta: u8,
15 k_len: u32,
16 v_len: u32,
17 expires_at: u64,
18}
19
20impl Header {
21 pub fn encode(&self) -> (usize, Vec<u8>) {
30 let mut buf = Vec::with_capacity(MAX_HEADER_SIZE);
31 buf.push(self.meta);
32 buf.push(self.user_meta);
33 let mut index = 2;
34
35 index += binary_put_uvariant_to_vec(&mut buf, self.k_len as u64);
36 index += binary_put_uvariant_to_vec(&mut buf, self.v_len as u64);
37 index += binary_put_uvariant_to_vec(&mut buf, self.expires_at);
38 (index, buf)
39 }
40
41 pub fn encode_to_bytes(&self) -> (usize, Bytes) {
51 let mut buf = BytesMut::with_capacity(MAX_HEADER_SIZE);
52 buf.put_u8(self.meta);
53 buf.put_u8(self.user_meta);
54 let mut index = 2;
55
56 index += binary_put_uvariant_to_bufmut(&mut buf, self.k_len as u64);
57 index += binary_put_uvariant_to_bufmut(&mut buf, self.v_len as u64);
58 index += binary_put_uvariant_to_bufmut(&mut buf, self.expires_at);
59 (index, buf.freeze())
60 }
61
62 pub fn decode(data: &[u8]) -> (usize, Self) {
64 let mut index = 2;
65 let (k_len, ctr) = binary_uvarint(&data[index..]);
66 index += ctr;
67
68 let (v_len, ctr) = binary_uvarint(&data[index..]);
69 index += ctr;
70
71 let (expires_at, ctr) = binary_uvarint(&data[index..]);
72 (
73 index + ctr,
74 Self {
75 k_len: k_len as u32,
76 v_len: v_len as u32,
77 expires_at,
78 meta: data[0],
79 user_meta: data[1],
80 },
81 )
82 }
83
84 #[cfg(feature = "std")]
86 pub fn decode_reader(
87 reader: &mut impl ByteReader,
88 hash_buf: &mut BytesMut,
89 ) -> std::io::Result<(usize, Self)> {
90 use crate::binary_read_and_put_uvarint;
91
92 let start = reader.position();
93 let meta = reader.read_byte()?;
94 hash_buf.put_u8(meta);
95 let user_meta = reader.read_byte()?;
96 hash_buf.put_u8(user_meta);
97
98 let k_len = binary_read_and_put_uvarint(reader, hash_buf)?;
99 let v_len = binary_read_and_put_uvarint(reader, hash_buf)?;
100 let expires_at = binary_read_and_put_uvarint(reader, hash_buf)?;
101 let h_len = reader.position() - start;
102 let h = Header {
103 k_len: k_len as u32,
104 v_len: v_len as u32,
105 expires_at,
106 meta,
107 user_meta,
108 };
109
110 Ok((h_len as usize, h))
111 }
112
113 pub fn update(&mut self, data: &[u8]) -> usize {
116 self.meta = data[0];
117 self.user_meta = data[1];
118 let mut index = 2;
119
120 let (k_len, ctr) = binary_uvarint(&data[index..]);
121 self.k_len = k_len as u32;
122 index += ctr;
123
124 let (v_len, ctr) = binary_uvarint(&data[index..]);
125 self.v_len = v_len as u32;
126 index += ctr;
127
128 let (expires_at, ctr) = binary_uvarint(&data[index..]);
129 self.expires_at = expires_at;
130 index + ctr
131 }
132
133 #[inline]
135 pub fn get_value_len(&self) -> u32 {
136 self.v_len
137 }
138
139 #[inline]
141 pub fn set_value_len(&mut self, vlen: u32) {
142 self.v_len = vlen
143 }
144
145 #[inline]
147 pub fn get_key_len(&self) -> u32 {
148 self.k_len
149 }
150
151 #[inline]
153 pub fn set_key_len(&mut self, klen: u32) {
154 self.k_len = klen
155 }
156
157 #[inline]
159 pub fn get_meta(&self) -> u8 {
160 self.meta
161 }
162
163 #[inline]
165 pub fn set_meta(&mut self, meta: u8) {
166 self.meta = meta
167 }
168
169 #[inline]
171 pub fn get_user_meta(&self) -> u8 {
172 self.user_meta
173 }
174
175 #[inline]
177 pub fn set_user_meta(&mut self, user_meta: u8) {
178 self.meta = user_meta
179 }
180
181 #[inline]
183 pub fn get_expires_at(&self) -> u64 {
184 self.expires_at
185 }
186
187 #[inline]
189 pub fn set_expires_at(&mut self, expires_at: u64) {
190 self.expires_at = expires_at
191 }
192}
193
194cfg_std! {
195 use std::io::Read;
196
197 pub trait ByteReader {
199 fn read_byte(&mut self) -> std::io::Result<u8>;
201 fn position(&self) -> u64;
203 }
204
205 macro_rules! impl_byte_reader_for_cursor {
206 ($($ty: ty),+ $(,)?) => {
207 $(
208 impl ByteReader for std::io::Cursor<$ty> {
209 #[inline]
210 fn read_byte(&mut self) -> std::io::Result<u8> {
211 let mut buf = [0; 1];
212 self.read_exact(&mut buf).map(|_| buf[0])
213 }
214
215 #[inline]
216 fn position(&self) -> u64 {
217 self.position()
218 }
219 }
220 )*
221 };
222 }
223
224 impl_byte_reader_for_cursor! {
225 Box<[u8]>,
226 &[u8],
227 &mut [u8],
228 Vec<u8>,
229 &Vec<u8>,
230 &mut Vec<u8>
231 }
232}