Functional Weave
Code in Rust

validation.email@1.0.0

README.md

2,558 bytes · view raw

# validation.email

THE ONLY TRUE VALIDATION OF AN EMAIL ADDRESS IS SENDING MAIL TO IT and seeing
the recipient act on the message. Syntax cannot tell you that a mailbox exists,
that it is still in use, or that it belongs to the person typing it. Use this to
catch typos while someone is still at the keyboard, then confirm by email. Do
not use it to decide an address is real, and do not use it to reject an address
a user insists is theirs without offering a way through.

This is a deliberate subset of RFC 5322, not an implementation of it. Nobody
should claim to implement RFC 5322: the real grammar admits comments, folded
whitespace, quoted strings containing spaces and bracketed IP literals, and
almost nothing downstream of a signup form can handle them. Accepting them here
would only let addresses through that the mail stack later rejects.

ACCEPTED: exactly one @; a local part of 1-64 characters (RFC 5321) made of
ASCII letters, digits and the atext specials ! # $ % & ' * + - / = ? ^ _ ` { | }
~ plus interior dots; a domain of two or more dot-separated labels, each 1-63
characters (RFC 1035) of ASCII letters, digits and interior hyphens; a top-level
label of two or more letters; a total length of at most 254 characters (RFC 5321
allows 256 octets for a forward path including the angle brackets).

REJECTED, on purpose: quoted local parts ("alice smith"@example.com); comments
and folded whitespace; bracketed IP literals (alice@[192.168.0.1]); bare
hostnames with no dot (alice@localhost) - valid mail locally, undeliverable from
anywhere else; all-numeric or single-letter top-level domains; leading, trailing
or doubled dots in the local part; any non-ASCII character, so internationalised
addresses must be punycoded before they reach this function; any leading or
trailing whitespace, because trimming is the caller's decision and silently
accepting " a@b.co" hides a paste bug.

Case is preserved and never significant to the answer. Local parts are
technically case-sensitive, so this capability does not lowercase anything;
emailDomain / email_domain lowercases only the domain half, where doing so is
safe.

No regular expressions are used, in any of the three languages. Rust has no
regex crate available here, and having all three walk the same character classes
in the same order is what makes the shared vectors meaningful rather than
coincidental.

Validators answer rather than throw: an unparseable value is not an exceptional
condition, it is the answer "no". A non-string argument is therefore false, not
a TypeError.