/// 身份证号脱敏: 保留前 3 位和后 4 位，中间用 **** 替代
pub fn mask_id_number(s: &str) -> String {
    let chars: Vec<char> = s.chars().collect();
    if chars.len() >= 7 {
        let head: String = chars[..3].iter().collect();
        let tail: String = chars[chars.len() - 4..].iter().collect();
        format!("{}****{}", head, tail)
    } else {
        "****".to_string()
    }
}

/// 手机号脱敏: 保留前 3 位和后 4 位，中间用 **** 替代
pub fn mask_phone(s: Option<&str>) -> Option<String> {
    s.map(|p| {
        let chars: Vec<char> = p.chars().collect();
        if chars.len() >= 7 {
            let head: String = chars[..3].iter().collect();
            let tail: String = chars[chars.len() - 4..].iter().collect();
            format!("{}****{}", head, tail)
        } else {
            "****".to_string()
        }
    })
}

/// 执业证号脱敏: 保留前 2 位和后 2 位，中间用 **** 替代
pub fn mask_license_number(s: &str) -> String {
    let chars: Vec<char> = s.chars().collect();
    if chars.len() >= 5 {
        let head: String = chars[..2].iter().collect();
        let tail: String = chars[chars.len() - 2..].iter().collect();
        format!("{}****{}", head, tail)
    } else {
        "****".to_string()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn mask_id_18_digits() {
        assert_eq!("110****1234", mask_id_number("110101199001011234"));
    }

    #[test]
    fn mask_id_short() {
        assert_eq!("****", mask_id_number("123456"));
    }

    #[test]
    fn mask_id_empty() {
        assert_eq!("****", mask_id_number(""));
    }

    #[test]
    fn mask_phone_normal() {
        assert_eq!(
            Some("138****5678".to_string()),
            mask_phone(Some("13812345678"))
        );
    }

    #[test]
    fn mask_phone_none() {
        assert_eq!(None, mask_phone(None));
    }

    #[test]
    fn mask_phone_short() {
        assert_eq!(Some("****".to_string()), mask_phone(Some("123")));
    }

    #[test]
    fn mask_phone_exactly_7() {
        assert_eq!(Some("123****4567".to_string()), mask_phone(Some("1234567")));
    }

    #[test]
    fn mask_id_exactly_7() {
        assert_eq!("123****4567", mask_id_number("1234567"));
    }

    #[test]
    fn mask_id_unicode_safe() {
        assert_eq!("你好世****cdef", mask_id_number("你好世界abcdef"));
    }

    #[test]
    fn mask_phone_unicode_safe() {
        assert_eq!(
            Some("你好世****cdef".to_string()),
            mask_phone(Some("你好世界abcdef"))
        );
    }

    #[test]
    fn mask_license_normal() {
        assert_eq!("YL****23", mask_license_number("YL-2024-00123"));
    }

    #[test]
    fn mask_license_short() {
        assert_eq!("****", mask_license_number("AB"));
    }

    #[test]
    fn mask_license_empty() {
        assert_eq!("****", mask_license_number(""));
    }
}
