Skip to main content

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}