apollo_redaction/strategy/
first4.rs1use crate::RedactionStrategy;
2use std::fmt;
3
4#[derive(Default, Clone)]
24pub struct First4Redactor;
25
26impl<T: AsRef<str>> RedactionStrategy<T> for First4Redactor {
27 fn display(&self, value: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 let s = value.as_ref();
29 let len = s.chars().count();
30
31 if len <= 4 {
32 write!(f, "****")
33 } else {
34 for c in s.chars().take(4) {
35 write!(f, "{c}")?;
36 }
37 write!(f, "****")
38 }
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::Redacted;
46
47 fn first4(input: &str) -> String {
48 Redacted::<_, First4Redactor>::new(input).to_string()
49 }
50
51 #[test]
52 fn test_first4() {
53 assert_eq!(first4("sk_live_abc123"), "sk_l****");
54 assert_eq!(first4("api_key_secret"), "api_****");
55 }
56
57 #[test]
58 fn test_short_input() {
59 assert_eq!(first4("abc"), "****");
60 assert_eq!(first4("abcd"), "****");
61 assert_eq!(first4("a"), "****");
62 assert_eq!(first4(""), "****");
63 }
64
65 #[test]
66 fn test_exactly_5_chars() {
67 assert_eq!(first4("12345"), "1234****");
68 }
69
70 #[test]
71 fn test_unicode() {
72 assert_eq!(first4("안녕하세요한글"), "안녕하세****");
73 }
74}