1pub mod frame;
4pub mod golden;
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8#[repr(u16)]
9pub enum FormatFamily {
10 Frame = 1,
12 Segment = 2,
14 VectorCodes = 3,
16 VectorFactors = 4,
18 VectorRescore = 5,
20 Columns = 6,
22 Alive = 7,
24 Postings = 8,
26 ChecksumTable = 9,
28 Manifest = 10,
30 Wal = 11,
32 GraphNodeBlocks = 12,
34 DocumentVersions = 13,
36 StoredMetadata = 14,
38 PurgeIntent = 15,
40 StoredText = 16,
42 NativeGraphObject = 17,
44 NativeGraphRoot = 18,
46 NativeGraphWal = 19,
48}
49
50impl FormatFamily {
51 #[must_use]
53 pub const fn id(self) -> u16 {
54 self as u16
55 }
56
57 pub(crate) const fn current_version(self) -> u16 {
58 match self {
59 Self::Manifest => 2,
60 Self::Frame
61 | Self::Segment
62 | Self::VectorCodes
63 | Self::VectorFactors
64 | Self::VectorRescore
65 | Self::Columns
66 | Self::Alive
67 | Self::Postings
68 | Self::ChecksumTable
69 | Self::Wal
70 | Self::GraphNodeBlocks
71 | Self::DocumentVersions
72 | Self::StoredMetadata
73 | Self::PurgeIntent
74 | Self::StoredText
75 | Self::NativeGraphObject
76 | Self::NativeGraphRoot
77 | Self::NativeGraphWal => 1,
78 }
79 }
80}
81
82#[derive(Clone, Copy, Debug, Eq, PartialEq)]
84pub struct FamilySpec {
85 pub family: FormatFamily,
87 pub current_version: u16,
89 pub minimum_accepted_version: u16,
91 pub maximum_accepted_version: u16,
93}
94
95#[derive(Clone, Copy, Debug, Eq, PartialEq)]
97pub enum RegistryError {
98 UnknownFamily(u16),
100 UnsupportedVersion {
102 family: u16,
104 version: u16,
106 minimum: u16,
108 maximum: u16,
110 },
111 RetiredScheme(u16),
113 UnknownScheme(u16),
115}
116
117impl std::fmt::Display for RegistryError {
118 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119 match self {
120 Self::UnknownFamily(family) => write!(formatter, "unknown format family {family}"),
121 Self::UnsupportedVersion {
122 family,
123 version,
124 minimum,
125 maximum,
126 } => write!(
127 formatter,
128 "format family {family} version {version} is outside accepted range {minimum}..={maximum}"
129 ),
130 Self::RetiredScheme(scheme) => {
131 write!(
132 formatter,
133 "quantization scheme id {scheme} is permanently retired"
134 )
135 }
136 Self::UnknownScheme(scheme) => {
137 write!(formatter, "unknown quantization scheme {scheme}")
138 }
139 }
140 }
141}
142
143impl std::error::Error for RegistryError {}
144
145pub struct FormatRegistry;
147
148const FAMILIES: [FamilySpec; 19] = [
149 FamilySpec {
150 family: FormatFamily::Frame,
151 current_version: 1,
152 minimum_accepted_version: 1,
153 maximum_accepted_version: 1,
154 },
155 FamilySpec {
156 family: FormatFamily::Segment,
157 current_version: 1,
158 minimum_accepted_version: 1,
159 maximum_accepted_version: 1,
160 },
161 FamilySpec {
162 family: FormatFamily::VectorCodes,
163 current_version: 1,
164 minimum_accepted_version: 1,
165 maximum_accepted_version: 1,
166 },
167 FamilySpec {
168 family: FormatFamily::VectorFactors,
169 current_version: 1,
170 minimum_accepted_version: 1,
171 maximum_accepted_version: 1,
172 },
173 FamilySpec {
174 family: FormatFamily::VectorRescore,
175 current_version: 1,
176 minimum_accepted_version: 1,
177 maximum_accepted_version: 1,
178 },
179 FamilySpec {
180 family: FormatFamily::Columns,
181 current_version: 1,
182 minimum_accepted_version: 1,
183 maximum_accepted_version: 1,
184 },
185 FamilySpec {
186 family: FormatFamily::Alive,
187 current_version: 1,
188 minimum_accepted_version: 1,
189 maximum_accepted_version: 1,
190 },
191 FamilySpec {
192 family: FormatFamily::Postings,
193 current_version: 1,
194 minimum_accepted_version: 1,
195 maximum_accepted_version: 1,
196 },
197 FamilySpec {
198 family: FormatFamily::ChecksumTable,
199 current_version: 1,
200 minimum_accepted_version: 1,
201 maximum_accepted_version: 1,
202 },
203 FamilySpec {
204 family: FormatFamily::Manifest,
205 current_version: 2,
206 minimum_accepted_version: 2,
207 maximum_accepted_version: 2,
208 },
209 FamilySpec {
210 family: FormatFamily::Wal,
211 current_version: 1,
212 minimum_accepted_version: 1,
213 maximum_accepted_version: 1,
214 },
215 FamilySpec {
216 family: FormatFamily::GraphNodeBlocks,
217 current_version: 1,
218 minimum_accepted_version: 1,
219 maximum_accepted_version: 1,
220 },
221 FamilySpec {
222 family: FormatFamily::DocumentVersions,
223 current_version: 1,
224 minimum_accepted_version: 1,
225 maximum_accepted_version: 1,
226 },
227 FamilySpec {
228 family: FormatFamily::StoredMetadata,
229 current_version: 1,
230 minimum_accepted_version: 1,
231 maximum_accepted_version: 1,
232 },
233 FamilySpec {
234 family: FormatFamily::PurgeIntent,
235 current_version: 1,
236 minimum_accepted_version: 1,
237 maximum_accepted_version: 1,
238 },
239 FamilySpec {
240 family: FormatFamily::StoredText,
241 current_version: 1,
242 minimum_accepted_version: 1,
243 maximum_accepted_version: 1,
244 },
245 FamilySpec {
246 family: FormatFamily::NativeGraphObject,
247 current_version: 1,
248 minimum_accepted_version: 1,
249 maximum_accepted_version: 1,
250 },
251 FamilySpec {
252 family: FormatFamily::NativeGraphRoot,
253 current_version: 1,
254 minimum_accepted_version: 1,
255 maximum_accepted_version: 1,
256 },
257 FamilySpec {
258 family: FormatFamily::NativeGraphWal,
259 current_version: 1,
260 minimum_accepted_version: 1,
261 maximum_accepted_version: 1,
262 },
263];
264
265impl FormatRegistry {
266 #[must_use]
268 pub const fn families() -> &'static [FamilySpec] {
269 &FAMILIES
270 }
271
272 pub fn require(family: u16, version: u16) -> Result<&'static FamilySpec, RegistryError> {
274 let spec = FAMILIES
275 .iter()
276 .find(|candidate| candidate.family.id() == family)
277 .ok_or(RegistryError::UnknownFamily(family))?;
278 if version < spec.minimum_accepted_version || version > spec.maximum_accepted_version {
279 return Err(RegistryError::UnsupportedVersion {
280 family,
281 version,
282 minimum: spec.minimum_accepted_version,
283 maximum: spec.maximum_accepted_version,
284 });
285 }
286 Ok(spec)
287 }
288
289 pub const fn require_scheme(scheme: u16) -> Result<(), RegistryError> {
291 match scheme {
292 0 | 1 | 2 | 4 => Ok(()),
293 3 | 5 => Err(RegistryError::RetiredScheme(scheme)),
294 _ => Err(RegistryError::UnknownScheme(scheme)),
295 }
296 }
297}