faf_rust_sdk/binary/
chunk_registry.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ChunkClassification {
15 Dna = 0b00,
17 Context = 0b01,
19 Pointer = 0b10,
21 Reserved = 0b11,
23}
24
25impl ChunkClassification {
26 pub const fn bits(&self) -> u32 {
28 *self as u32
29 }
30
31 pub fn from_bits(bits: u32) -> Self {
33 match bits & 0b11 {
34 0b00 => Self::Dna,
35 0b01 => Self::Context,
36 0b10 => Self::Pointer,
37 _ => Self::Reserved,
38 }
39 }
40
41 pub const fn name(&self) -> &'static str {
43 match self {
44 Self::Dna => "DNA",
45 Self::Context => "Context",
46 Self::Pointer => "Pointer",
47 Self::Reserved => "Reserved",
48 }
49 }
50}
51
52pub const CLASSIFICATION_MASK: u32 = 0b11;
54
55pub const DNA_KEYS: &[&str] = &[
57 "faf_version",
58 "project",
59 "instant_context",
60 "tech_stack",
61 "key_files",
62 "commands",
63 "architecture",
64 "context",
65 "bi_sync",
66 "meta",
67];
68
69pub const POINTER_KEY: &str = "docs";
71
72pub fn classify_key(key: &str) -> ChunkClassification {
74 if key == POINTER_KEY {
75 ChunkClassification::Pointer
76 } else if DNA_KEYS.contains(&key) {
77 ChunkClassification::Dna
78 } else {
79 ChunkClassification::Context
80 }
81}
82
83pub fn default_priority_for_classification(classification: ChunkClassification) -> u8 {
85 match classification {
86 ChunkClassification::Dna => 200, ChunkClassification::Context => 64, ChunkClassification::Pointer => 128, ChunkClassification::Reserved => 0, }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_all_dna_keys_classified() {
99 for key in DNA_KEYS {
100 assert_eq!(
101 classify_key(key),
102 ChunkClassification::Dna,
103 "Expected '{}' to be DNA",
104 key
105 );
106 }
107 }
108
109 #[test]
110 fn test_pointer_key() {
111 assert_eq!(classify_key("docs"), ChunkClassification::Pointer);
112 }
113
114 #[test]
115 fn test_unknown_keys_are_context() {
116 assert_eq!(classify_key("custom_field"), ChunkClassification::Context);
117 assert_eq!(classify_key("my_data"), ChunkClassification::Context);
118 assert_eq!(classify_key("anything"), ChunkClassification::Context);
119 }
120
121 #[test]
122 fn test_case_sensitivity() {
123 assert_eq!(classify_key("Project"), ChunkClassification::Context);
125 assert_eq!(classify_key("DOCS"), ChunkClassification::Context);
126 assert_eq!(classify_key("project"), ChunkClassification::Dna);
127 }
128
129 #[test]
130 fn test_bits_roundtrip() {
131 for class in &[
132 ChunkClassification::Dna,
133 ChunkClassification::Context,
134 ChunkClassification::Pointer,
135 ChunkClassification::Reserved,
136 ] {
137 assert_eq!(ChunkClassification::from_bits(class.bits()), *class);
138 }
139 }
140
141 #[test]
142 fn test_bit_values() {
143 assert_eq!(ChunkClassification::Dna.bits(), 0b00);
144 assert_eq!(ChunkClassification::Context.bits(), 0b01);
145 assert_eq!(ChunkClassification::Pointer.bits(), 0b10);
146 assert_eq!(ChunkClassification::Reserved.bits(), 0b11);
147 }
148
149 #[test]
150 fn test_from_bits_masked() {
151 assert_eq!(
153 ChunkClassification::from_bits(0xFF00_0000),
154 ChunkClassification::Dna
155 );
156 assert_eq!(
157 ChunkClassification::from_bits(0xFF00_0001),
158 ChunkClassification::Context
159 );
160 }
161
162 #[test]
163 fn test_classification_names() {
164 assert_eq!(ChunkClassification::Dna.name(), "DNA");
165 assert_eq!(ChunkClassification::Context.name(), "Context");
166 assert_eq!(ChunkClassification::Pointer.name(), "Pointer");
167 assert_eq!(ChunkClassification::Reserved.name(), "Reserved");
168 }
169
170 #[test]
171 fn test_default_priorities() {
172 assert_eq!(
173 default_priority_for_classification(ChunkClassification::Dna),
174 200
175 );
176 assert_eq!(
177 default_priority_for_classification(ChunkClassification::Context),
178 64
179 );
180 assert_eq!(
181 default_priority_for_classification(ChunkClassification::Pointer),
182 128
183 );
184 }
185}