oxigdal_security/anonymization/
masking.rs1pub enum MaskingStrategy {
5 Full(char),
7 Partial {
9 keep_first: usize,
11 keep_last: usize,
13 mask_char: char,
15 },
16 Email,
18 CreditCard,
20}
21
22impl MaskingStrategy {
23 pub fn apply(&self, input: &str) -> String {
25 match self {
26 MaskingStrategy::Full(mask_char) => mask_char.to_string().repeat(input.len()),
27 MaskingStrategy::Partial {
28 keep_first,
29 keep_last,
30 mask_char,
31 } => {
32 if input.len() <= keep_first + keep_last {
33 return input.to_string();
34 }
35 let first = &input[..*keep_first];
36 let last = &input[input.len() - keep_last..];
37 let mask_len = input.len() - keep_first - keep_last;
38 format!(
39 "{}{}{}",
40 first,
41 mask_char.to_string().repeat(mask_len),
42 last
43 )
44 }
45 MaskingStrategy::Email => {
46 if let Some(at_pos) = input.find('@') {
47 let username = &input[..at_pos];
48 let domain = &input[at_pos..];
49 if username.len() <= 2 {
50 format!("**{}", domain)
51 } else {
52 format!("{}***{}", &username[..1], domain)
53 }
54 } else {
55 MaskingStrategy::Full('*').apply(input)
56 }
57 }
58 MaskingStrategy::CreditCard => {
59 if input.len() >= 4 {
60 format!("****-****-****-{}", &input[input.len() - 4..])
61 } else {
62 MaskingStrategy::Full('*').apply(input)
63 }
64 }
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_full_masking() {
75 let strategy = MaskingStrategy::Full('*');
76 assert_eq!(strategy.apply("secret"), "******");
77 }
78
79 #[test]
80 fn test_partial_masking() {
81 let strategy = MaskingStrategy::Partial {
82 keep_first: 2,
83 keep_last: 2,
84 mask_char: '*',
85 };
86 assert_eq!(strategy.apply("1234567890"), "12******90");
87 }
88
89 #[test]
90 fn test_email_masking() {
91 let strategy = MaskingStrategy::Email;
92 assert_eq!(strategy.apply("user@example.com"), "u***@example.com");
93 }
94
95 #[test]
96 fn test_credit_card_masking() {
97 let strategy = MaskingStrategy::CreditCard;
98 assert_eq!(strategy.apply("1234567812345678"), "****-****-****-5678");
99 }
100}