maskify 0.1.0

Zero-dependency, blazing-fast Rust crate for masking sensitive data — emails, phones, cards, Aadhaar, PAN, IPs & more. Comes with trait extensions and a builder pattern.
Documentation
//! # maskify
//!
//! A zero-dependency, blazing-fast Rust crate for masking sensitive data.
//!
//! Built by [Daniyal Masih](https://github.com/daniyalmasih) — a senior Rust developer
//! focused on building high-quality, production-ready crates for the Rust ecosystem.
//!
//! ## Supported Data Types
//! - 📧 Email addresses
//! - 📱 Phone numbers
//! - 💳 Credit/Debit card numbers
//! - 👤 Names
//! - 🌐 IP addresses (IPv4 & IPv6)
//! - 🪪 Aadhaar numbers (India)
//! - 🪪 PAN card numbers (India)
//! - ⚙️  Custom masking with builder pattern
//!
//! ## Quick Start
//! ```rust
//! use maskify::MaskExt;
//!
//! let email = "user@example.com";
//! assert_eq!(email.mask_email(), "u***@example.com");
//!
//! let phone = "9876543210";
//! assert_eq!(phone.mask_phone(), "98******10");
//! ```

mod maskers;
mod builder;

pub use maskers::{
    mask_email, mask_phone, mask_card, mask_all,
    mask_name, mask_ip, mask_aadhaar, mask_pan, mask_custom,
};
pub use builder::Masker;

/// Extension trait — call masking methods directly on `&str` and `String`.
///
/// This trait lets you write clean, readable code like:
/// ```rust
/// use maskify::MaskExt;
/// let masked = "user@example.com".mask_email();
/// ```
pub trait MaskExt {
    /// Mask an email address — keeps first char of local part, masks rest.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("user@example.com".mask_email(), "u***@example.com");
    /// ```
    fn mask_email(&self) -> String;

    /// Mask a phone number — shows first 2 and last 2 digits.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("9876543210".mask_phone(), "98******10");
    /// ```
    fn mask_phone(&self) -> String;

    /// Mask a card number — shows first 4 and last 4 digits.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("4111111111111111".mask_card(), "4111********1111");
    /// ```
    fn mask_card(&self) -> String;

    /// Mask entire string with asterisks.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("secret".mask_all(), "******");
    /// ```
    fn mask_all(&self) -> String;

    /// Mask a name — keeps first letter of each word.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("John Doe".mask_name(), "J*** D**");
    /// ```
    fn mask_name(&self) -> String;

    /// Mask an IP address — shows only first octet.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("192.168.1.100".mask_ip(), "192.*.*.*");
    /// ```
    fn mask_ip(&self) -> String;

    /// Mask an Aadhaar number — shows only last 4 digits.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("123456789012".mask_aadhaar(), "XXXX-XXXX-9012");
    /// ```
    fn mask_aadhaar(&self) -> String;

    /// Mask a PAN number — keeps first and last character.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("ABCDE1234F".mask_pan(), "A********F");
    /// ```
    fn mask_pan(&self) -> String;

    /// Custom masking — specify how many chars to keep at start/end and mask char.
    ///
    /// ```rust
    /// use maskify::MaskExt;
    /// assert_eq!("HelloWorld".mask_custom(2, 2, '#'), "He######ld");
    /// ```
    fn mask_custom(&self, keep_start: usize, keep_end: usize, mask_char: char) -> String;
}

impl MaskExt for str {
    fn mask_email(&self) -> String {
        maskers::mask_email(self)
    }

    fn mask_phone(&self) -> String {
        maskers::mask_phone(self)
    }

    fn mask_card(&self) -> String {
        maskers::mask_card(self)
    }

    fn mask_all(&self) -> String {
        maskers::mask_all(self)
    }

    fn mask_name(&self) -> String {
        maskers::mask_name(self)
    }

    fn mask_ip(&self) -> String {
        maskers::mask_ip(self)
    }

    fn mask_aadhaar(&self) -> String {
        maskers::mask_aadhaar(self)
    }

    fn mask_pan(&self) -> String {
        maskers::mask_pan(self)
    }

    fn mask_custom(&self, keep_start: usize, keep_end: usize, mask_char: char) -> String {
        maskers::mask_custom(self, keep_start, keep_end, mask_char)
    }
}