pub fn mask_email(input: &str) -> String {
if input.is_empty() {
return String::new();
}
match input.split_once('@') {
Some((local, domain)) => {
let chars: Vec<char> = local.chars().collect();
let masked_local = match chars.len() {
0 | 1 => String::from("*"),
n @ 2..=4 => {
format!("{}{}", chars[0], "*".repeat(n - 1))
}
_ => {
format!("{}****", chars[0])
}
};
format!("{}@{}", masked_local, domain)
}
None => mask_all(input),
}
}
pub fn mask_phone(input: &str) -> String {
let digits: Vec<char> = input.chars().filter(|c| c.is_ascii_digit()).collect();
let len = digits.len();
if len == 0 {
return String::new();
}
if len <= 4 {
return "*".repeat(len);
}
let start: String = digits[..2].iter().collect();
let end: String = digits[len - 2..].iter().collect();
let middle = "*".repeat(len - 4);
format!("{}{}{}", start, middle, end)
}
pub fn mask_card(input: &str) -> String {
let digits: Vec<char> = input.chars().filter(|c| c.is_ascii_digit()).collect();
let len = digits.len();
if len == 0 {
return String::new();
}
if len <= 8 {
return "*".repeat(len);
}
let start: String = digits[..4].iter().collect();
let end: String = digits[len - 4..].iter().collect();
let middle = "*".repeat(len - 8);
format!("{}{}{}", start, middle, end)
}
pub fn mask_all(input: &str) -> String {
"*".repeat(input.chars().count())
}
pub fn mask_name(input: &str) -> String {
if input.is_empty() {
return String::new();
}
input
.split_whitespace()
.map(|word| {
let chars: Vec<char> = word.chars().collect();
match chars.len() {
0 => String::new(),
1 => chars[0].to_string(),
n => format!("{}{}", chars[0], "*".repeat(n - 1)),
}
})
.collect::<Vec<_>>()
.join(" ")
}
pub fn mask_ip(input: &str) -> String {
if input.is_empty() {
return String::new();
}
let parts: Vec<&str> = input.split('.').collect();
if parts.len() == 4 {
return format!("{}.*.*.*", parts[0]);
}
if input.contains(':') {
let parts: Vec<&str> = input.split(':').collect();
if parts.len() >= 2 {
let masked_groups: Vec<&str> = std::iter::once(parts[0])
.chain(std::iter::repeat("****").take(parts.len() - 1))
.collect();
return masked_groups.join(":");
}
}
mask_custom(input, 3, 0, '*')
}
pub fn mask_aadhaar(input: &str) -> String {
let digits: Vec<char> = input.chars().filter(|c| c.is_ascii_digit()).collect();
if digits.len() != 12 {
return mask_all(input);
}
let last4: String = digits[8..].iter().collect();
format!("XXXX-XXXX-{}", last4)
}
pub fn mask_pan(input: &str) -> String {
let chars: Vec<char> = input.chars().collect();
if chars.len() != 10 {
return mask_all(input);
}
format!("{}{}{}", chars[0], "*".repeat(8), chars[9])
}
pub fn mask_custom(input: &str, keep_start: usize, keep_end: usize, mask_char: char) -> String {
let chars: Vec<char> = input.chars().collect();
let len = chars.len();
if len == 0 {
return String::new();
}
if keep_start + keep_end >= len {
return input.to_string();
}
let start: String = chars[..keep_start].iter().collect();
let end: String = if keep_end > 0 {
chars[len - keep_end..].iter().collect()
} else {
String::new()
};
let middle_len = len - keep_start - keep_end;
let middle: String = std::iter::repeat(mask_char).take(middle_len).collect();
format!("{}{}{}", start, middle, end)
}