cipherstash_config/column/index/ste_vec_mode.rs
1use serde::{Deserialize, Serialize};
2
3/// Selects the per-entry orderable-term primitive used by a `ste_vec` index.
4///
5/// Selectors are always Blake3-keyed and term-side MACs are always
6/// HMAC-SHA256 in both modes; only the ordering term differs. Indexes
7/// produced under different modes are not cross-comparable, so the indexing
8/// side and the query side must agree on the mode for results to match.
9#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
10#[serde(rename_all = "kebab-case")]
11pub enum SteVecMode {
12 /// CLLW OPE — order-preserving ciphertexts carried on the sv-level `op`
13 /// key. Ciphertext bytes compare in plain byte order, so the database
14 /// needs no ORE-aware comparator. This is the EQL v3 / Supabase-compatible
15 /// mode, and the default.
16 #[default]
17 Compat,
18 /// CLLW ORE — ciphertexts carried on the sv-level `oc` key, compared with
19 /// an ORE-aware comparator. The legacy v2 protocol, still used by Proxy /
20 /// v2 consumers.
21 Standard,
22}
23
24#[cfg(test)]
25mod tests {
26 use super::SteVecMode;
27 use serde_json::json;
28
29 #[test]
30 fn test_default_is_compat() {
31 assert_eq!(SteVecMode::default(), SteVecMode::Compat);
32 }
33
34 #[test]
35 fn test_serializes_kebab_case() {
36 assert_eq!(
37 serde_json::to_value(SteVecMode::Compat).unwrap(),
38 json!("compat")
39 );
40 assert_eq!(
41 serde_json::to_value(SteVecMode::Standard).unwrap(),
42 json!("standard")
43 );
44 }
45
46 #[test]
47 fn test_deserializes_kebab_case() {
48 let compat: SteVecMode = serde_json::from_value(json!("compat")).unwrap();
49 let standard: SteVecMode = serde_json::from_value(json!("standard")).unwrap();
50 assert_eq!(compat, SteVecMode::Compat);
51 assert_eq!(standard, SteVecMode::Standard);
52 }
53}