lxdb_format/
adjacency_record.rs1use crate::{BinaryRecord, FormatError};
2pub const ADJACENCY_RECORD_SIZE: usize = 16;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct AdjacencyRecord {
11 offset: u64,
12 count: u32,
13}
14
15impl AdjacencyRecord {
16 pub const SIZE: usize = ADJACENCY_RECORD_SIZE;
17
18 pub const fn new(offset: u64, count: u32) -> Self {
19 Self { offset, count }
20 }
21
22 pub const fn offset(self) -> u64 {
23 self.offset
24 }
25
26 pub const fn count(self) -> u32 {
27 self.count
28 }
29
30 pub const fn end(self) -> u64 {
31 self.offset + self.count as u64
32 }
33
34 pub fn encode(self) -> [u8; ADJACENCY_RECORD_SIZE] {
35 let mut bytes = [0_u8; ADJACENCY_RECORD_SIZE];
36
37 bytes[0..8].copy_from_slice(&self.offset.to_le_bytes());
38 bytes[8..12].copy_from_slice(&self.count.to_le_bytes());
39
40 bytes
43 }
44
45 pub fn decode(bytes: &[u8]) -> Result<Self, FormatError> {
46 if bytes.len() != Self::SIZE {
47 return Err(FormatError::UnexpectedRecordSize {
48 record: "adjacency record",
49 expected: Self::SIZE,
50 found: bytes.len(),
51 });
52 }
53
54 let offset = u64::from_le_bytes(
55 bytes[0..8].try_into().expect("adjacency offset must occupy eight bytes"),
56 );
57
58 let count = u32::from_le_bytes(
59 bytes[8..12].try_into().expect("adjacency count must occupy four bytes"),
60 );
61
62 Ok(Self::new(offset, count))
63 }
64}
65
66impl BinaryRecord for AdjacencyRecord {
67 const SIZE: usize = AdjacencyRecord::SIZE;
68
69 fn decode(bytes: &[u8]) -> Result<Self, FormatError> {
70 AdjacencyRecord::decode(bytes)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::{ADJACENCY_RECORD_SIZE, AdjacencyRecord};
77
78 #[test]
79 fn encodes_adjacency_record() {
80 let record = AdjacencyRecord::new(1_024, 17);
81
82 let bytes = record.encode();
83
84 assert_eq!(bytes.len(), ADJACENCY_RECORD_SIZE);
85
86 assert_eq!(
87 u64::from_le_bytes([
88 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
89 ]),
90 1_024
91 );
92
93 assert_eq!(u32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11],]), 17);
94
95 assert_eq!(&bytes[12..16], &[0; 4]);
96 }
97
98 #[test]
99 fn calculates_relation_range_end() {
100 let record = AdjacencyRecord::new(25, 12);
101
102 assert_eq!(record.end(), 37);
103 }
104
105 #[test]
106 fn supports_tokens_without_relations() {
107 let record = AdjacencyRecord::new(50, 0);
108
109 let bytes = record.encode();
110
111 assert_eq!(record.offset(), 50);
112 assert_eq!(record.count(), 0);
113 assert_eq!(record.end(), 50);
114 assert_eq!(&bytes[8..12], &[0; 4]);
115 }
116}