|
| 1 | +//! # 📬 emval |
| 2 | +//! |
| 3 | +//! `emval` is a blazingly fast email validator written in Rust with Python bindings, offering performance improvements of 100-1000x over traditional validators. |
| 4 | +//! |
| 5 | +//!  |
| 6 | +
|
| 7 | +//! ## Features |
| 8 | +
|
| 9 | +//! - Drop-in replacement for popular email validators like `python-email-validator`, `verify-email`, and `pyIsEmail`. |
| 10 | +//! - 100-1000x faster than [python-email-validator](https://github.com/JoshData/python-email-validator). |
| 11 | +//! - Validates email address syntax according to [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322.html) and [RFC 6531](https://www.rfc-editor.org/rfc/rfc6531.html). |
| 12 | +//! - Checks domain deliverability (coming soon). |
| 13 | +//! - Supports internationalized domain names (IDN) and local parts. |
| 14 | +//! - Provides user-friendly syntax errors. |
| 15 | +//! - Normalizes addresses. |
| 16 | +//! - Rejects invalid and unsafe Unicode characters. |
| 17 | +//! |
| 18 | +//! ## Getting Started |
| 19 | +//! |
| 20 | +//! Install `emval` from PyPI: |
| 21 | +//! |
| 22 | +//! ```sh |
| 23 | +//! pip install emval |
| 24 | +//! ``` |
| 25 | +//! |
| 26 | +//! or use `emval` in a Rust project: |
| 27 | +//! ```sh |
| 28 | +//! cargo add emval |
| 29 | +//! ``` |
| 30 | +//! |
| 31 | +//! ## Usage |
| 32 | +//! |
| 33 | +//! ### Quick Start |
| 34 | +//! |
| 35 | +//! To validate an email address in Python: |
| 36 | +//! |
| 37 | +//! ```python |
| 38 | +//! from emval import validate_email, EmailValidator |
| 39 | +//! |
| 40 | + |
| 41 | +//! |
| 42 | +//! try: |
| 43 | +//! # Check if the email is valid. |
| 44 | +//! val_email = validate_email(email) |
| 45 | +//! # Utilize the normalized form for storage. |
| 46 | +//! normalized_email = val_email.normalized |
| 47 | +//! except Exception as e: |
| 48 | +//! # Example: "Invalid Local Part: Quoting the local part before the '@' sign is not permitted in this context." |
| 49 | +//! print(str(e)) |
| 50 | +//! ``` |
| 51 | +//! |
| 52 | +//! The same code in Rust: |
| 53 | +//! ```rust |
| 54 | +//! use emval::{validate_email, ValidationError}; |
| 55 | +//! |
| 56 | +//! fn main() -> Result<(), ValidationError> { |
| 57 | +//! let email = "[email protected]"; |
| 58 | +//! let val_email = validate_email(email)?; |
| 59 | +//! let normalized_email = val_email.normalized; |
| 60 | +//! Ok(()) |
| 61 | +//! } |
| 62 | +//! ``` |
| 63 | +//! |
| 64 | +//! ### Configurations |
| 65 | +//! |
| 66 | +//! Customize email validation behavior using the `EmailValidator` class: |
| 67 | +//! |
| 68 | +//! ```python |
| 69 | +//! from emval import EmailValidator |
| 70 | +//! |
| 71 | +//! emval = EmailValidator( |
| 72 | +//! allow_smtputf8=False, |
| 73 | +//! allow_empty_local=True, |
| 74 | +//! allow_quoted_local=True, |
| 75 | +//! allow_domain_literal=True, |
| 76 | +//! deliverable_address=False, |
| 77 | +//! ) |
| 78 | +//! |
| 79 | +//! email = "user@[192.168.1.1]" |
| 80 | +//! |
| 81 | +//! try: |
| 82 | +//! validated_email = emval.validate_email(email) |
| 83 | +//! print(validated_email) |
| 84 | +//! except Exception as e: |
| 85 | +//! print(str(e)) |
| 86 | +//! ``` |
| 87 | +//! |
| 88 | +//! The same code in Rust: |
| 89 | +//! ```rust |
| 90 | +//! use emval::{EmailValidator, ValidationError}; |
| 91 | +//! |
| 92 | +//! fn main() -> Result<(), ValidationError> { |
| 93 | +//! let emval = EmailValidator { |
| 94 | +//! allow_smtputf8: false, |
| 95 | +//! allow_empty_local: true, |
| 96 | +//! allow_quoted_local: true, |
| 97 | +//! allow_domain_literal: true, |
| 98 | +//! deliverable_address: false, |
| 99 | +//! }; |
| 100 | +//! |
| 101 | +//! let email = "[email protected]"; |
| 102 | +//! let validated_email = emval.validate_email(email)?; |
| 103 | +//! Ok(()) |
| 104 | +//! } |
| 105 | +//! ``` |
| 106 | +//! |
| 107 | +//! ### Options |
| 108 | +//! |
| 109 | +//! - `allow_smtputf8`: Allows internationalized email addresses. |
| 110 | +//! - `allow_empty_local`: Allows an empty local part (e.g., `@domain.com`). |
| 111 | +//! - `allow_quoted_local`: Allows quoted local parts (e.g., `"user name"@domain.com`). |
| 112 | +//! - `allow_domain_literal`: Allows domain literals (e.g., `[192.168.0.1]`). |
| 113 | +//! - `deliverable_address`: Checks if the email address is deliverable by verifying the domain's MX records. |
| 114 | +//! |
| 115 | +//! ## Technical Details |
| 116 | +//! |
| 117 | +//! ### Email Address Syntax |
| 118 | +//! |
| 119 | +//! emval adheres to the syntax rules defined in [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322.html) and [RFC 6531](https://www.rfc-editor.org/rfc/rfc6531.html). It supports both ASCII and internationalized characters. |
| 120 | +//! |
| 121 | +//! ### Internationalized Email Addresses |
| 122 | +//! |
| 123 | +//! #### Domain Names |
| 124 | +//! |
| 125 | +//! emval converts non-ASCII domain names into their ASCII "Punycode" form according to [IDNA 2008](https://www.rfc-editor.org/rfc/rfc5891.html). This ensures compatibility with systems that do not support Unicode. |
| 126 | +//! |
| 127 | +//! #### Local Parts |
| 128 | +//! |
| 129 | +//! emval allows international characters in the local part of email addresses, following [RFC 6531](https://www.rfc-editor.org/rfc/rfc6531.html). It offers options to handle environments without SMTPUTF8 support. |
| 130 | +//! |
| 131 | +//! ### Unsafe Unicode Characters |
| 132 | +//! |
| 133 | +//! emval rejects unsafe Unicode characters to enhance security, preventing display and interpretation issues. |
| 134 | +//! |
| 135 | +//! ### Normalization |
| 136 | +//! |
| 137 | +//! emval normalizes email addresses to ensure consistency: |
| 138 | +//! |
| 139 | +//! - **Lowercasing domains:** Domain names are standardized to lowercase. |
| 140 | +//! - **Unicode NFC normalization:** Characters are transformed into their precomposed forms. |
| 141 | +//! - **Removing unnecessary characters:** Quotes and backslashes in the local part are removed. |
| 142 | +//! |
| 143 | +//! ## Acknowledgements |
| 144 | +//! |
| 145 | +//! This project draws inspiration from [python-email-validator](https://github.com/JoshData/python-email-validator). While `python-email-validator` is more comprehensive, `emval` aims to provide a faster solution. |
| 146 | +//! |
| 147 | +//! ## Getting Help |
| 148 | +//! |
| 149 | +//! For questions and issues, please open an issue in the [GitHub issue tracker](https://github.com/bnkc/emval/issues). |
| 150 | +//! |
| 151 | +//! ## License |
| 152 | +//! |
| 153 | +//! emval is licensed under the [MIT License](https://opensource.org/licenses/MIT). See the [LICENSE](https://github.com/bnkc/emval/blob/main/LICENSE) file for more details. |
| 154 | +
|
1 | 155 | #![feature(ip)]
|
2 | 156 | #[macro_use]
|
3 | 157 | extern crate lazy_static;
|
4 | 158 | mod consts;
|
5 |
| -mod errors; |
| 159 | +pub mod errors; |
6 | 160 | mod models;
|
7 | 161 | mod validators;
|
8 | 162 |
|
| 163 | +pub use crate::errors::ValidationError; |
| 164 | +pub use crate::models::{EmailValidator, ValidatedEmail}; |
| 165 | + |
| 166 | +/// Validate an email with default validator settings. |
| 167 | +pub fn validate_email<T: AsRef<str>>(email: T) -> Result<ValidatedEmail, ValidationError> { |
| 168 | + let validator = EmailValidator::default(); |
| 169 | + validator.validate_email(email.as_ref()) |
| 170 | +} |
| 171 | + |
9 | 172 | use pyo3::prelude::*;
|
10 | 173 |
|
11 | 174 | #[pymodule]
|
|
0 commit comments