feophantlib/engine/io/page_formats/
item_id_data.rs

1//! Pointer type to indicate where an item is inside a page
2//! See here for doc: https://www.postgresql.org/docs/current/storage-page-layout.html
3use crate::engine::io::{
4    format_traits::{Parseable, Serializable},
5    ConstEncodedSize,
6};
7
8use super::{UInt12, UInt12Error};
9use bytes::{Buf, BufMut};
10use std::ops::Range;
11use thiserror::Error;
12
13#[derive(Clone, Copy, Debug, PartialEq)]
14pub struct ItemIdData {
15    offset: UInt12,
16    pub length: UInt12,
17}
18
19impl ItemIdData {
20    pub fn new(offset: UInt12, length: UInt12) -> ItemIdData {
21        ItemIdData { offset, length }
22    }
23
24    pub fn get_range(&self) -> Range<usize> {
25        let offset_usize = self.offset.to_u16() as usize;
26        let length_usize = self.length.to_u16() as usize;
27        offset_usize..(offset_usize + length_usize)
28    }
29}
30
31impl ConstEncodedSize for ItemIdData {
32    fn encoded_size() -> usize {
33        3
34    }
35}
36
37impl Parseable<ItemIdDataError> for ItemIdData {
38    type Output = Self;
39    fn parse(buffer: &mut impl Buf) -> Result<Self, ItemIdDataError> {
40        let items = UInt12::parse_packed(buffer, 2)?;
41        Ok(ItemIdData::new(items[0], items[1]))
42    }
43}
44
45impl Serializable for ItemIdData {
46    fn serialize(&self, buffer: &mut impl BufMut) {
47        UInt12::serialize_packed(buffer, &[self.offset, self.length]);
48    }
49}
50
51#[derive(Debug, Error)]
52pub enum ItemIdDataError {
53    #[error("Not enough data has {0} bytes")]
54    InsufficentData(usize),
55    #[error(transparent)]
56    UInt12Error(#[from] UInt12Error),
57}
58
59#[cfg(test)]
60mod tests {
61    use bytes::BytesMut;
62
63    use crate::constants::PAGE_SIZE;
64
65    use super::*;
66
67    #[test]
68    fn test_roundtrip() -> Result<(), Box<dyn std::error::Error>> {
69        let iid = ItemIdData::new(UInt12::new(1)?, UInt12::new(2)?);
70
71        let mut buffer = BytesMut::with_capacity(PAGE_SIZE as usize);
72        iid.serialize(&mut buffer);
73
74        let mut buffer = buffer.freeze();
75        let result = ItemIdData::parse(&mut buffer)?;
76
77        assert_eq!(iid, result);
78
79        Ok(())
80    }
81}