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// Reserved: bits 6-15 for future use
25
26/// Helper struct for working with flags
27#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
28pub struct Flags(pub u16);
29
30impl Flags {
31    /// Create new empty flags
32    pub const fn new() -> Self {
33        Self(0)
34    }
35
36    /// Create flags from raw u16
37    pub const fn from_raw(raw: u16) -> Self {
38        Self(raw)
39    }
40
41    /// Get raw u16 value
42    pub const fn raw(&self) -> u16 {
43        self.0
44    }
45
46    /// Check if compressed flag is set
47    pub const fn is_compressed(&self) -> bool {
48        self.0 & FLAG_COMPRESSED != 0
49    }
50
51    /// Check if embeddings flag is set
52    pub const fn has_embeddings(&self) -> bool {
53        self.0 & FLAG_EMBEDDINGS != 0
54    }
55
56    /// Check if tokenized flag is set
57    pub const fn is_tokenized(&self) -> bool {
58        self.0 & FLAG_TOKENIZED != 0
59    }
60
61    /// Check if weighted flag is set
62    pub const fn has_weights(&self) -> bool {
63        self.0 & FLAG_WEIGHTED != 0
64    }
65
66    /// Check if model hints flag is set
67    pub const fn has_model_hints(&self) -> bool {
68        self.0 & FLAG_MODEL_HINTS != 0
69    }
70
71    /// Check if signed flag is set
72    pub const fn is_signed(&self) -> bool {
73        self.0 & FLAG_SIGNED != 0
74    }
75
76    /// Set compressed flag
77    pub fn set_compressed(&mut self, value: bool) {
78        if value {
79            self.0 |= FLAG_COMPRESSED;
80        } else {
81            self.0 &= !FLAG_COMPRESSED;
82        }
83    }
84
85    /// Set embeddings flag
86    pub fn set_embeddings(&mut self, value: bool) {
87        if value {
88            self.0 |= FLAG_EMBEDDINGS;
89        } else {
90            self.0 &= !FLAG_EMBEDDINGS;
91        }
92    }
93
94    /// Set tokenized flag
95    pub fn set_tokenized(&mut self, value: bool) {
96        if value {
97            self.0 |= FLAG_TOKENIZED;
98        } else {
99            self.0 &= !FLAG_TOKENIZED;
100        }
101    }
102
103    /// Set weighted flag
104    pub fn set_weighted(&mut self, value: bool) {
105        if value {
106            self.0 |= FLAG_WEIGHTED;
107        } else {
108            self.0 &= !FLAG_WEIGHTED;
109        }
110    }
111
112    /// Set model hints flag
113    pub fn set_model_hints(&mut self, value: bool) {
114        if value {
115            self.0 |= FLAG_MODEL_HINTS;
116        } else {
117            self.0 &= !FLAG_MODEL_HINTS;
118        }
119    }
120
121    /// Set signed flag
122    pub fn set_signed(&mut self, value: bool) {
123        if value {
124            self.0 |= FLAG_SIGNED;
125        } else {
126            self.0 &= !FLAG_SIGNED;
127        }
128    }
129}
130
131impl From<u16> for Flags {
132    fn from(raw: u16) -> Self {
133        Self(raw)
134    }
135}
136
137impl From<Flags> for u16 {
138    fn from(flags: Flags) -> Self {
139        flags.0
140    }
141}
142
143#[cfg(test)]
144mod tests {
145    use super::*;
146
147    #[test]
148    fn test_flag_bits() {
149        assert_eq!(FLAG_COMPRESSED, 1);
150        assert_eq!(FLAG_EMBEDDINGS, 2);
151        assert_eq!(FLAG_TOKENIZED, 4);
152        assert_eq!(FLAG_WEIGHTED, 8);
153        assert_eq!(FLAG_MODEL_HINTS, 16);
154        assert_eq!(FLAG_SIGNED, 32);
155    }
156
157    #[test]
158    fn test_flags_default() {
159        let flags = Flags::new();
160        assert_eq!(flags.raw(), 0);
161        assert!(!flags.is_compressed());
162        assert!(!flags.has_embeddings());
163    }
164
165    #[test]
166    fn test_flags_set_get() {
167        let mut flags = Flags::new();
168        flags.set_compressed(true);
169        flags.set_embeddings(true);
170
171        assert!(flags.is_compressed());
172        assert!(flags.has_embeddings());
173        assert!(!flags.is_tokenized());
174
175        assert_eq!(flags.raw(), FLAG_COMPRESSED | FLAG_EMBEDDINGS);
176    }
177
178    #[test]
179    fn test_flags_unset() {
180        let mut flags = Flags::from_raw(FLAG_COMPRESSED | FLAG_EMBEDDINGS);
181        flags.set_compressed(false);
182
183        assert!(!flags.is_compressed());
184        assert!(flags.has_embeddings());
185    }
186}