feophantlib/engine/io/page_formats/
item_id_data.rs1use 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}