agentic_reality/format/
sections.rs1use crate::types::error::{RealityError, RealityResult};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[repr(u16)]
8pub enum SectionType {
9 Deployment = 0x0001,
10 Environment = 0x0002,
11 Resource = 0x0003,
12 Reality = 0x0004,
13 Topology = 0x0005,
14 Temporal = 0x0006,
15 Stakes = 0x0007,
16 Coherence = 0x0008,
17 Indexes = 0x0009,
18}
19
20impl SectionType {
21 pub fn from_u16(v: u16) -> RealityResult<Self> {
22 match v {
23 0x0001 => Ok(Self::Deployment),
24 0x0002 => Ok(Self::Environment),
25 0x0003 => Ok(Self::Resource),
26 0x0004 => Ok(Self::Reality),
27 0x0005 => Ok(Self::Topology),
28 0x0006 => Ok(Self::Temporal),
29 0x0007 => Ok(Self::Stakes),
30 0x0008 => Ok(Self::Coherence),
31 0x0009 => Ok(Self::Indexes),
32 _ => Err(RealityError::InvalidFormat(format!(
33 "unknown section type: 0x{:04X}",
34 v
35 ))),
36 }
37 }
38}
39
40#[derive(Debug, Clone)]
42pub struct SectionEntry {
43 pub section_type: SectionType,
44 pub flags: u16,
45 pub offset: u64,
46 pub length: u64,
47 pub uncompressed_length: u64,
48 pub checksum: [u8; 8],
49}
50
51pub const SECTION_ENTRY_SIZE: usize = 2 + 2 + 8 + 8 + 8 + 8; impl SectionEntry {
55 pub fn write_to(&self, buf: &mut Vec<u8>) {
56 buf.extend_from_slice(&(self.section_type as u16).to_le_bytes());
57 buf.extend_from_slice(&self.flags.to_le_bytes());
58 buf.extend_from_slice(&self.offset.to_le_bytes());
59 buf.extend_from_slice(&self.length.to_le_bytes());
60 buf.extend_from_slice(&self.uncompressed_length.to_le_bytes());
61 buf.extend_from_slice(&self.checksum);
62 }
63
64 pub fn read_from(data: &[u8]) -> RealityResult<Self> {
65 if data.len() < SECTION_ENTRY_SIZE {
66 return Err(RealityError::InvalidFormat(
67 "section entry too short".into(),
68 ));
69 }
70 let section_type = SectionType::from_u16(u16::from_le_bytes(
71 data[0..2]
72 .try_into()
73 .map_err(|_| RealityError::InvalidFormat("section_type".into()))?,
74 ))?;
75 let flags = u16::from_le_bytes(
76 data[2..4]
77 .try_into()
78 .map_err(|_| RealityError::InvalidFormat("flags".into()))?,
79 );
80 let offset = u64::from_le_bytes(
81 data[4..12]
82 .try_into()
83 .map_err(|_| RealityError::InvalidFormat("offset".into()))?,
84 );
85 let length = u64::from_le_bytes(
86 data[12..20]
87 .try_into()
88 .map_err(|_| RealityError::InvalidFormat("length".into()))?,
89 );
90 let uncompressed_length = u64::from_le_bytes(
91 data[20..28]
92 .try_into()
93 .map_err(|_| RealityError::InvalidFormat("uncompressed_length".into()))?,
94 );
95 let checksum: [u8; 8] = data[28..36]
96 .try_into()
97 .map_err(|_| RealityError::InvalidFormat("checksum".into()))?;
98
99 Ok(Self {
100 section_type,
101 flags,
102 offset,
103 length,
104 uncompressed_length,
105 checksum,
106 })
107 }
108}