fern_masking/
strategies.rs1use bytes::{BufMut, Bytes, BytesMut};
5use std::fmt::Debug;
6
7pub trait MaskingStrategy: Debug + Send + Sync {
11 fn mask(&self, data: &Bytes) -> Bytes;
12}
13
14#[derive(Debug)]
17pub struct CaviarMask {
18 length: usize,
19}
20
21impl CaviarMask {
22 pub const fn new(length: usize) -> Self {
23 Self { length }
24 }
25}
26
27impl MaskingStrategy for CaviarMask {
28 fn mask(&self, data: &Bytes) -> Bytes {
29 log::trace!(" original value: {:?}", data);
30
31 let mut res = BytesMut::with_capacity(self.length);
32 res.put_bytes(b'*', self.length);
33
34 log::trace!("rewritten value: {:?}", res);
35 res.freeze()
36 }
37}
38
39#[derive(Debug)]
43pub struct CaviarShapeMask;
44
45impl CaviarShapeMask {
46 pub const fn new() -> Self {
47 Self
48 }
49}
50
51impl MaskingStrategy for CaviarShapeMask {
52 fn mask(&self, data: &Bytes) -> Bytes {
54 log::trace!(" original value: {:?}", data);
55
56 let mut res = BytesMut::with_capacity(data.len());
57 for c in data.iter() {
58 if (*c as char).is_alphanumeric() {
59 res.put_u8(b'*');
60 } else {
61 res.put_u8(*c);
62 }
63 }
64
65 log::trace!("rewritten value: {:?}", res);
66 res.freeze()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use bytes::Bytes;
74
75 #[test]
76 fn valid_caviar_empty_data() {
77 let data = Bytes::from_static(b"");
78 let expected = Bytes::from_static(b"******");
79
80 let strategy = CaviarMask::new(6);
81 let masked = strategy.mask(&data);
82 assert_eq!(expected, masked, "masked data");
83 }
84
85 #[test]
86 fn valid_caviar_single_char_data() {
87 let data = Bytes::from_static(b"P");
88 let expected = Bytes::from_static(b"******");
89
90 let strategy = CaviarMask::new(6);
91 let masked = strategy.mask(&data);
92 assert_eq!(expected, masked, "masked data");
93 }
94
95 #[test]
96 fn valid_caviar_shape_empty_data() {
97 let data = Bytes::from_static(b"");
98 let expected = Bytes::from_static(b"");
99
100 let strategy = CaviarShapeMask::new();
101 let masked = strategy.mask(&data);
102 assert_eq!(expected, masked, "masked data");
103 }
104
105 #[test]
106 fn valid_caviar_shape_single_hyphen_data() {
107 let data = Bytes::from_static(b"abcd-efgh");
108 let expected = Bytes::from_static(b"****-****");
109
110 let strategy = CaviarShapeMask::new();
111 let masked = strategy.mask(&data);
112 assert_eq!(expected, masked, "masked data");
113 }
114}