1use bytemuck::{Pod, Zeroable};
4
5#[derive(Debug, Clone, Copy, Pod, Zeroable)]
7#[repr(C)]
8pub struct DrvHeader {
9 pub magic: [u8; 4],
11 pub version: u16,
13 pub flags: u16,
15 pub section_count: u32,
17 pub checksum: u32,
19}
20
21impl DrvHeader {
22 pub fn new(section_count: u32) -> Self {
24 Self {
25 magic: *b"DRV\0",
26 version: super::DRV_VERSION,
27 flags: 0,
28 section_count,
29 checksum: 0,
30 }
31 }
32
33 pub fn validate(&self) -> crate::Result<()> {
35 if &self.magic != b"DRV\0" {
36 return Err(crate::DrivenError::InvalidBinary(
37 "Invalid magic bytes".to_string(),
38 ));
39 }
40 if self.version > super::DRV_VERSION {
41 return Err(crate::DrivenError::InvalidBinary(format!(
42 "Unsupported version: {} (max supported: {})",
43 self.version,
44 super::DRV_VERSION
45 )));
46 }
47 Ok(())
48 }
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
53#[repr(u8)]
54pub enum RuleCategory {
55 Style = 0,
57 Naming = 1,
59 ErrorHandling = 2,
61 Testing = 3,
63 Documentation = 4,
65 Security = 5,
67 Performance = 6,
69 Architecture = 7,
71 Imports = 8,
73 Git = 9,
75 Api = 10,
77 Other = 255,
79}
80
81impl From<u8> for RuleCategory {
82 fn from(value: u8) -> Self {
83 match value {
84 0 => RuleCategory::Style,
85 1 => RuleCategory::Naming,
86 2 => RuleCategory::ErrorHandling,
87 3 => RuleCategory::Testing,
88 4 => RuleCategory::Documentation,
89 5 => RuleCategory::Security,
90 6 => RuleCategory::Performance,
91 7 => RuleCategory::Architecture,
92 8 => RuleCategory::Imports,
93 9 => RuleCategory::Git,
94 10 => RuleCategory::Api,
95 _ => RuleCategory::Other,
96 }
97 }
98}
99
100#[derive(Debug, Clone)]
102pub struct RuleEntry {
103 pub category: RuleCategory,
105 pub priority: u8,
107 pub description_idx: u32,
109 pub pattern_idx: u32,
111}
112
113#[derive(Debug, Clone, Default)]
115pub struct PersonaSection {
116 pub name_idx: u32,
118 pub role_idx: u32,
120 pub identity_idx: u32,
122 pub style_idx: u32,
124 pub traits: Vec<u32>,
126 pub principles: Vec<u32>,
128}
129
130#[derive(Debug, Clone, Default)]
132pub struct StandardsSection {
133 pub rules: Vec<RuleEntry>,
135}
136
137#[derive(Debug, Clone, Default)]
139pub struct ContextSection {
140 pub include_patterns: Vec<u32>,
142 pub exclude_patterns: Vec<u32>,
144 pub focus_areas: Vec<u32>,
146 pub dependencies: Vec<(u32, u32)>,
148}
149
150#[derive(Debug, Clone)]
152pub struct WorkflowStep {
153 pub name_idx: u32,
155 pub description_idx: u32,
157 pub condition_idx: u32,
159 pub actions: Vec<u32>,
161}
162
163#[derive(Debug, Clone, Default)]
165pub struct WorkflowSection {
166 pub name_idx: u32,
168 pub steps: Vec<WorkflowStep>,
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn test_header_size() {
178 assert_eq!(std::mem::size_of::<DrvHeader>(), 16);
179 }
180
181 #[test]
182 fn test_header_validation() {
183 let valid = DrvHeader::new(3);
184 assert!(valid.validate().is_ok());
185
186 let invalid = DrvHeader {
187 magic: *b"BAD\0",
188 ..valid
189 };
190 assert!(invalid.validate().is_err());
191 }
192
193 #[test]
194 fn test_rule_category_roundtrip() {
195 for i in 0..=10 {
196 let cat = RuleCategory::from(i);
197 assert_eq!(cat as u8, i);
198 }
199 assert_eq!(RuleCategory::from(100), RuleCategory::Other);
201 }
202}