umadb_core/
slice_reader.rs1use crate::common::{PageID, Position, Tsn};
2use crate::tags_tree_nodes::{TAG_HASH_LEN, get_tag_key_width};
3use umadb_dcb::{DcbError, DcbResult};
4use uuid::Uuid;
5
6pub struct SliceReader<'a> {
8 slice: &'a [u8],
9}
10
11impl<'a> SliceReader<'a> {
12 pub fn new(slice: &'a [u8]) -> Self {
13 Self { slice }
14 }
15
16 pub fn read_bytes(&mut self, len: usize) -> DcbResult<&'a [u8]> {
18 if self.slice.len() < len {
19 return Err(DcbError::DeserializationError(format!(
20 "Unexpected end of data. Needed {len} bytes, {} remaining",
21 self.slice.len()
22 )));
23 }
24 let (head, tail) = self.slice.split_at(len);
25 self.slice = tail;
26 Ok(head)
27 }
28
29 pub fn read_u8(&mut self) -> DcbResult<u8> {
30 let b = self.read_bytes(1)?;
31 Ok(b[0])
32 }
33
34 pub fn read_u16(&mut self) -> DcbResult<u16> {
35 let b = self.read_bytes(2)?;
36 Ok(u16::from_le_bytes(b.try_into().unwrap()))
37 }
38
39 pub fn read_u32(&mut self) -> DcbResult<u32> {
40 let b = self.read_bytes(4)?;
41 Ok(u32::from_le_bytes(b.try_into().unwrap()))
42 }
43
44 pub fn read_u64(&mut self) -> DcbResult<u64> {
45 let b = self.read_bytes(8)?;
46 Ok(u64::from_le_bytes(b.try_into().unwrap()))
47 }
48
49 pub fn read_uuid(&mut self) -> DcbResult<Uuid> {
50 let bytes = self.read_bytes(16)?;
51 Uuid::from_slice(bytes)
52 .map_err(|e| DcbError::DeserializationError(format!("Invalid UUID sequence: {e}")))
53 }
54
55 pub fn read_page_id(&mut self) -> DcbResult<PageID> {
56 Ok(PageID(self.read_u64()?))
57 }
58
59 pub fn read_position(&mut self) -> DcbResult<Position> {
60 Ok(Position(self.read_u64()?))
61 }
62
63 pub fn read_tsn(&mut self) -> DcbResult<Tsn> {
64 Ok(Tsn(self.read_u64()?))
65 }
66
67 pub fn read_str(&mut self, len: usize) -> DcbResult<&'a str> {
69 let bytes = self.read_bytes(len)?;
70 std::str::from_utf8(bytes)
71 .map_err(|_| DcbError::DeserializationError("Invalid UTF-8 sequence".to_string()))
72 }
73
74 pub fn read_string(&mut self, len: usize) -> DcbResult<String> {
76 let s = self.read_str(len)?;
78 Ok(s.to_string())
79 }
80
81 pub fn read_tag_hash(&mut self) -> DcbResult<[u8; TAG_HASH_LEN]> {
83 let keyw = get_tag_key_width();
84 let key_bytes = self.read_bytes(keyw)?;
85
86 let mut key = [0u8; TAG_HASH_LEN];
87 key[..keyw].copy_from_slice(key_bytes);
89
90 Ok(key)
91 }
92
93 pub fn remaining(&self) -> usize {
95 self.slice.len()
96 }
97}