Skip to main content

sql_splitter/redactor/strategy/
constant.rs

1//! Constant strategy - replace values with a fixed constant.
2
3use super::{RedactValue, Strategy, StrategyKind};
4
5/// Strategy that replaces all non-NULL values with a constant
6#[derive(Debug, Clone)]
7pub struct ConstantStrategy {
8    value: String,
9}
10
11impl ConstantStrategy {
12    pub fn new(value: String) -> Self {
13        Self { value }
14    }
15}
16
17impl Strategy for ConstantStrategy {
18    fn apply(&self, value: &RedactValue, _rng: &mut dyn rand::RngCore) -> RedactValue {
19        // Preserve NULL values, replace everything else with constant
20        if value.is_null() {
21            RedactValue::Null
22        } else {
23            RedactValue::String(self.value.clone())
24        }
25    }
26
27    fn kind(&self) -> StrategyKind {
28        StrategyKind::Constant {
29            value: self.value.clone(),
30        }
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37    use rand::SeedableRng;
38
39    #[test]
40    fn test_constant_strategy() {
41        let strategy = ConstantStrategy::new("REDACTED".to_string());
42        let mut rng = rand::rngs::StdRng::seed_from_u64(42);
43
44        // String becomes constant
45        let result = strategy.apply(&RedactValue::String("secret".to_string()), &mut rng);
46        match result {
47            RedactValue::String(s) => assert_eq!(s, "REDACTED"),
48            _ => panic!("Expected String"),
49        }
50
51        // Integer becomes constant
52        let result = strategy.apply(&RedactValue::Integer(123), &mut rng);
53        match result {
54            RedactValue::String(s) => assert_eq!(s, "REDACTED"),
55            _ => panic!("Expected String"),
56        }
57
58        // NULL stays NULL
59        let result = strategy.apply(&RedactValue::Null, &mut rng);
60        assert!(matches!(result, RedactValue::Null));
61    }
62
63    #[test]
64    fn test_password_hash_constant() {
65        let strategy = ConstantStrategy::new("$2b$10$REDACTED_PASSWORD_HASH".to_string());
66        let mut rng = rand::rngs::StdRng::seed_from_u64(42);
67
68        let result = strategy.apply(
69            &RedactValue::String("$2b$10$real_hash_here".to_string()),
70            &mut rng,
71        );
72        match result {
73            RedactValue::String(s) => assert_eq!(s, "$2b$10$REDACTED_PASSWORD_HASH"),
74            _ => panic!("Expected String"),
75        }
76    }
77}