use crate::RedactionStrategy;
use std::fmt;
#[derive(Clone)]
pub struct FixedRedactor<const N: usize>;
impl<const N: usize> Default for FixedRedactor<N> {
fn default() -> Self {
Self
}
}
impl<T: AsRef<str>, const N: usize> RedactionStrategy<T> for FixedRedactor<N> {
fn display(&self, value: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = value.as_ref();
let len = s.chars().count();
if len <= N {
return write!(f, "****");
}
for c in s.chars().take(N) {
write!(f, "{c}")?;
}
write!(f, "****")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Redacted;
fn fixed<const N: usize>(input: &str) -> String {
Redacted::<_, FixedRedactor<N>>::new(input).to_string()
}
#[test]
fn test_fixed_4() {
assert_eq!(fixed::<4>("password123"), "pass****");
assert_eq!(fixed::<4>("test1"), "test****");
assert_eq!(fixed::<4>("test1234"), "test****");
assert_eq!(fixed::<4>("test12345"), "test****");
}
#[test]
fn test_fixed_2() {
assert_eq!(fixed::<2>("test1"), "te****");
assert_eq!(fixed::<2>("testing"), "te****");
}
#[test]
fn test_short_input() {
assert_eq!(fixed::<4>("abc"), "****");
assert_eq!(fixed::<4>("ab"), "****");
assert_eq!(fixed::<4>("test"), "****");
assert_eq!(fixed::<4>(""), "****");
}
#[test]
fn test_fixed_0() {
assert_eq!(fixed::<0>("testing"), "****");
assert_eq!(fixed::<0>("test"), "****");
assert_eq!(fixed::<0>(""), "****");
}
#[test]
fn test_unicode() {
assert_eq!(fixed::<4>("안녕하세요한글"), "안녕하세****");
}
}