Skip to main content

faf_rust_sdk/binary/
flags.rs

1//! FAFB Feature Flags
2//!
3//! Bit flags for optional features in .fafb files.
4//! Readers MUST ignore unknown flags and continue processing.
5
6/// Content is zstd compressed
7pub const FLAG_COMPRESSED: u16 = 0b0000_0000_0000_0001;
8
9/// Contains pre-computed embeddings
10pub const FLAG_EMBEDDINGS: u16 = 0b0000_0000_0000_0010;
11
12/// Contains token boundaries
13pub const FLAG_TOKENIZED: u16 = 0b0000_0000_0000_0100;
14
15/// Contains attention weights
16pub const FLAG_WEIGHTED: u16 = 0b0000_0000_0000_1000;
17
18/// Contains model-specific hints
19pub const FLAG_MODEL_HINTS: u16 = 0b0000_0000_0001_0000;
20
21/// Contains cryptographic signature
22pub const FLAG_SIGNED: u16 = 0b0000_0000_0010_0000;
23
24/// Contains a string table (always set in unified format)
25pub const FLAG_STRING_TABLE: u16 = 0b0000_0000_0100_0000;
26
27/// File is output of chain resolution (enterprise)
28pub const FLAG_RESOLVED: u16 = 0b0000_0000_1000_0000;
29
30// Reserved: bits 8-15 for future use
31
32/// Helper struct for working with flags
33#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
34pub struct Flags(pub u16);
35
36impl Flags {
37    /// Create new empty flags
38    pub const fn new() -> Self {
39        Self(0)
40    }
41
42    /// Create flags from raw u16
43    pub const fn from_raw(raw: u16) -> Self {
44        Self(raw)
45    }
46
47    /// Get raw u16 value
48    pub const fn raw(&self) -> u16 {
49        self.0
50    }
51
52    /// Check if compressed flag is set
53    pub const fn is_compressed(&self) -> bool {
54        self.0 & FLAG_COMPRESSED != 0
55    }
56
57    /// Check if embeddings flag is set
58    pub const fn has_embeddings(&self) -> bool {
59        self.0 & FLAG_EMBEDDINGS != 0
60    }
61
62    /// Check if tokenized flag is set
63    pub const fn is_tokenized(&self) -> bool {
64        self.0 & FLAG_TOKENIZED != 0
65    }
66
67    /// Check if weighted flag is set
68    pub const fn has_weights(&self) -> bool {
69        self.0 & FLAG_WEIGHTED != 0
70    }
71
72    /// Check if model hints flag is set
73    pub const fn has_model_hints(&self) -> bool {
74        self.0 & FLAG_MODEL_HINTS != 0
75    }
76
77    /// Check if signed flag is set
78    pub const fn is_signed(&self) -> bool {
79        self.0 & FLAG_SIGNED != 0
80    }
81
82    /// Set compressed flag
83    pub fn set_compressed(&mut self, value: bool) {
84        if value {
85            self.0 |= FLAG_COMPRESSED;
86        } else {
87            self.0 &= !FLAG_COMPRESSED;
88        }
89    }
90
91    /// Set embeddings flag
92    pub fn set_embeddings(&mut self, value: bool) {
93        if value {
94            self.0 |= FLAG_EMBEDDINGS;
95        } else {
96            self.0 &= !FLAG_EMBEDDINGS;
97        }
98    }
99
100    /// Set tokenized flag
101    pub fn set_tokenized(&mut self, value: bool) {
102        if value {
103            self.0 |= FLAG_TOKENIZED;
104        } else {
105            self.0 &= !FLAG_TOKENIZED;
106        }
107    }
108
109    /// Set weighted flag
110    pub fn set_weighted(&mut self, value: bool) {
111        if value {
112            self.0 |= FLAG_WEIGHTED;
113        } else {
114            self.0 &= !FLAG_WEIGHTED;
115        }
116    }
117
118    /// Set model hints flag
119    pub fn set_model_hints(&mut self, value: bool) {
120        if value {
121            self.0 |= FLAG_MODEL_HINTS;
122        } else {
123            self.0 &= !FLAG_MODEL_HINTS;
124        }
125    }
126
127    /// Set signed flag
128    pub fn set_signed(&mut self, value: bool) {
129        if value {
130            self.0 |= FLAG_SIGNED;
131        } else {
132            self.0 &= !FLAG_SIGNED;
133        }
134    }
135
136    /// Check if string table flag is set
137    pub const fn has_string_table(&self) -> bool {
138        self.0 & FLAG_STRING_TABLE != 0
139    }
140
141    /// Set string table flag
142    pub fn set_string_table(&mut self, value: bool) {
143        if value {
144            self.0 |= FLAG_STRING_TABLE;
145        } else {
146            self.0 &= !FLAG_STRING_TABLE;
147        }
148    }
149
150    /// Check if resolved flag is set (enterprise chain resolution)
151    pub const fn is_resolved(&self) -> bool {
152        self.0 & FLAG_RESOLVED != 0
153    }
154
155    /// Set resolved flag (enterprise chain resolution)
156    pub fn set_resolved(&mut self, value: bool) {
157        if value {
158            self.0 |= FLAG_RESOLVED;
159        } else {
160            self.0 &= !FLAG_RESOLVED;
161        }
162    }
163}
164
165impl From<u16> for Flags {
166    fn from(raw: u16) -> Self {
167        Self(raw)
168    }
169}
170
171impl From<Flags> for u16 {
172    fn from(flags: Flags) -> Self {
173        flags.0
174    }
175}
176
177#[cfg(test)]
178mod tests {
179    use super::*;
180
181    #[test]
182    fn test_flag_bits() {
183        assert_eq!(FLAG_COMPRESSED, 1);
184        assert_eq!(FLAG_EMBEDDINGS, 2);
185        assert_eq!(FLAG_TOKENIZED, 4);
186        assert_eq!(FLAG_WEIGHTED, 8);
187        assert_eq!(FLAG_MODEL_HINTS, 16);
188        assert_eq!(FLAG_SIGNED, 32);
189        assert_eq!(FLAG_STRING_TABLE, 64);
190        assert_eq!(FLAG_RESOLVED, 128);
191    }
192
193    #[test]
194    fn test_flags_default() {
195        let flags = Flags::new();
196        assert_eq!(flags.raw(), 0);
197        assert!(!flags.is_compressed());
198        assert!(!flags.has_embeddings());
199    }
200
201    #[test]
202    fn test_flags_set_get() {
203        let mut flags = Flags::new();
204        flags.set_compressed(true);
205        flags.set_embeddings(true);
206
207        assert!(flags.is_compressed());
208        assert!(flags.has_embeddings());
209        assert!(!flags.is_tokenized());
210
211        assert_eq!(flags.raw(), FLAG_COMPRESSED | FLAG_EMBEDDINGS);
212    }
213
214    #[test]
215    fn test_flags_unset() {
216        let mut flags = Flags::from_raw(FLAG_COMPRESSED | FLAG_EMBEDDINGS);
217        flags.set_compressed(false);
218
219        assert!(!flags.is_compressed());
220        assert!(flags.has_embeddings());
221    }
222
223    #[test]
224    fn test_resolved_flag() {
225        let mut flags = Flags::new();
226        assert!(!flags.is_resolved());
227        flags.set_resolved(true);
228        assert!(flags.is_resolved());
229        assert_eq!(flags.raw() & FLAG_RESOLVED, FLAG_RESOLVED);
230    }
231}