┌────────────────────────────────┐
│ eMail address parser/validator │
└────────────────────────────────┘

The purpose of this library is primarily to enable users to verify
eMail addresses, which cannot be done with a regular expression.
More eMail-related parsers, validators, emitters, etc. later.

Preliminary release note
────────────────────────

The first version of this library has a tight deadline. As such,
it only parses address/mailbox lists and their dependents and can
validate, using eMail rules, localparts and domains (IP address or
FQDN, also usable separately).

Installation
────────────

Add a suitable dependency to your project, for example with Maven:

<dependency>
	<groupId>org.evolvis.tartools</groupId>
	<artifactId>rfc822</artifactId>
	<version>0.1</version>
</dependency>

Make sure your project can handle Java 8 bytecode.

Usage
─────

To validate an eMail address, you first get a parser instance:

	final String address = "user <localpart@domain>";
	final Path p = Path.of(address);

If address was null or too long (we’re generous here), this
will return null. Otherwise, you have a parser and call it:

	import lombok.val;

	val mailbox = p.forSender(false); // Path.Address
	val address = p.forSender(true);  // Path.Address
	val mbxList = p.asMailboxList();  // Path.AddressList
	val adrList = p.asAddressList();  // Path.AddressList

(Using “val” means the protected type can be stored.)

The return value if null if the address cannot be parsed. The
first thing to do now is, with To: for example, to weed out
parsable but invalid input (e.g. bad domain or IP or too long):

	if (!adrList.isValid()) {
		LOG.error("invalid recipients: {}", adrList.invalidsToString());
		return null;
	}

Afterwards, decide what you wish to do with the result. Mostly,
you’ll intend to send out eMails, which needs just addresses:

	return adrList.flattenAddrSpecs();  // List<String>

You can also validate hostnames…

	final String hostname = "foo.example.com";
	final boolean ok = FQDN.isDomain(hostname);

… and IP addresses, both IP and Legacy IP (a.k.a. IPv4):

	final String ip = "2001:db8::1";
	final InetAddress ip = IPAddress.v6(ip);

This API is what you get in the 0.1 release. (There are several
other methods, especially toString() is useful.)

Limitations
───────────

This API checks for both RFC5322 and RFC5321 compliance, with
several others (DNS) influencing. It’s intended to be used by
eMail senders towards public internet which limits, among the
allowed lengths and characters, features:

• IPv6 Zone identifiers (ff02::1%vr0) aren’t valid as they
  are strictly host-specific

• General-address-literal isn’t permitted, as (other than
  IPv6 addresses) there currently isn’t any usable tag

• display-name must be valid ASCII dot-atom, or quoted-string
  (but no tabs), syntax

Future directions
─────────────────

Pass more of the structure up (comments, for example).

Add a DWIM mode that parses semicolons as list separators as
well and MIME-encodes problematic headers, so we can handle:

	Es „ß“ Zett <sz@example.com>; Shaun D. Mäh <sheep@example.com>

Sorry, no time…

More patches, improvements, tests, etc. are of course welcome!
