Skip to main content

driven/format/
mod.rs

1//! Binary Rule Format (.drv - Driven Rule)
2//!
3//! Zero-copy binary format for AI coding rules, achieving 75% size reduction
4//! and 50-150x faster parsing compared to text-based formats.
5//!
6//! ## Format Structure
7//!
8//! ```text
9//! DrivenRule (.drv)
10//! ├── Header (16 bytes)
11//! │   ├── Magic: "DRV\0" (4 bytes)
12//! │   ├── Version: u16 (2 bytes)
13//! │   ├── Flags: u16 (2 bytes)
14//! │   ├── Section Count: u32 (4 bytes)
15//! │   └── Checksum: u32 (4 bytes - Blake3 truncated)
16//! │
17//! ├── String Table (variable)
18//! │   ├── Count: u32
19//! │   └── Strings: [length: u16, bytes: [u8; length]]...
20//! │
21//! ├── Persona Section (optional)
22//! ├── Standards Section (optional)
23//! ├── Context Section (optional)
24//! └── Workflow Section (optional)
25//! ```
26
27mod decoder;
28mod encoder;
29mod schema;
30mod versioning;
31
32pub use decoder::DrvDecoder;
33pub use encoder::DrvEncoder;
34pub use schema::{
35    ContextSection, DrvHeader, PersonaSection, RuleCategory, RuleEntry, StandardsSection,
36    WorkflowSection, WorkflowStep,
37};
38pub use versioning::{FormatVersion, VersionMigrator};
39
40/// Magic bytes for .drv files
41pub const DRV_MAGIC: [u8; 4] = *b"DRV\0";
42
43/// Current format version
44pub const DRV_VERSION: u16 = 1;
45
46/// Section type identifiers
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
48#[repr(u8)]
49pub enum SectionType {
50    /// String table section
51    StringTable = 0x01,
52    /// Persona definition
53    Persona = 0x02,
54    /// Coding standards
55    Standards = 0x03,
56    /// Project context
57    Context = 0x04,
58    /// Workflow definition
59    Workflow = 0x05,
60}
61
62impl TryFrom<u8> for SectionType {
63    type Error = crate::DrivenError;
64
65    fn try_from(value: u8) -> Result<Self, Self::Error> {
66        match value {
67            0x01 => Ok(SectionType::StringTable),
68            0x02 => Ok(SectionType::Persona),
69            0x03 => Ok(SectionType::Standards),
70            0x04 => Ok(SectionType::Context),
71            0x05 => Ok(SectionType::Workflow),
72            _ => Err(crate::DrivenError::InvalidBinary(format!(
73                "Unknown section type: 0x{:02x}",
74                value
75            ))),
76        }
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_magic_bytes() {
86        assert_eq!(&DRV_MAGIC, b"DRV\0");
87    }
88
89    #[test]
90    fn test_section_type_roundtrip() {
91        let types = [
92            SectionType::StringTable,
93            SectionType::Persona,
94            SectionType::Standards,
95            SectionType::Context,
96            SectionType::Workflow,
97        ];
98
99        for t in types {
100            let byte = t as u8;
101            let back = SectionType::try_from(byte).unwrap();
102            assert_eq!(t, back);
103        }
104    }
105}