curtissimo/elm-email-parser/1.1.0

Curtissimo.Email

This module provides an email address parsing implementation that complies with

That's pretty cool, but not quite what most of us want from an email address parser because it allows email addresses like "this\@is/\vgreat"@[ foo ]. (I know, right?)

So, the parser is configurable to allow you greater control over the whole weird email address thing.

The anatomy of an email address

RFC 2822 - Internet Message Format specifies that an email address has two parts:

  • The local part which is the stuff before the @ symbol
  • The domain part which is the stuff after the @ symbol

The local part

RFC 2822 - Internet Message Format specifies two different formats for the local part of an email address:

  • The dot-atom format which is what you are most likely used to, like firstName.lastName
  • The quoted-string format which is the Chaos Monkey of local parts letting you put pretty much anything between two double quotes, like "this\@is/\vgreat"

Plus addressing

Many modern email providers allow you to perform so-called "plus addressing," where anything after a + symbol in the local part is completely ignored when delivering the email. Thus, the emails [email protected] and [email protected] would deliver to the same mailbox.

This parser supports the identification of plus addressing. In the terminology of this parser, the content before the + symbol is the stem and the content after the + symbols is the plus.

The domain part

RFC 2822 - Internet Message Format specifies two different formats for the domain part of an email address:

  • The dot-atom format which is what you are most likely used to, like example.com
  • The domain-literal format which is the Chaos Monkey of domain parts letting you put pretty much anything between square brackets, like [this \bis/\vgreat\t] (bells and vertical tabs, anyone?)

Configuration

type alias ParseOptions =
{ allowDomainLiterals : Bool
, allowQuotedLocals : Bool
, allowUnicode : Bool
}

Allows you to allow or prevent types of email parts or content when your code converts a String to an Email.

  • allowDomainLiterals: If set to True, then the parser will recognize what RFC 2822 refers to as "domain literals." A domain literal starts with a [, ends with an ], and allows letters, whitespace, and ASCII control characters between the square brackets.
  • allowQuotedLocals: If set to True, then the parser will recognize what RFC 2822 refers to as "quoted strings" as the local part of the email address. A quoted string starts and ends with " (double quotes), and allows letters, whitespace, and escaped letters between the quotes.
  • allowUnicode: If set to True, then the parser will allow Unicode alphanumeric characters in the local part and domain part.
defaultOptions : ParseOptions

Provides a ParseOptions with all flags set to False which is pretty sensible.

Use

fromString : ParseOptions -> String -> Result (List Int) Email

Converts a String to an Email using the provided ParseOptions.

If the input is invalid, returns a list of columnar positions where the parser failed to recognize the input.

toString : Email -> String

Converts an Email to a String.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map toString
--> Ok "[email protected]"
validate : ParseOptions -> String -> Maybe String

A convenience function to validate an email address.

Returns the email address if it's valid. Returns Nothing otherwise.

"[email protected]"
    |> validate defaultOptions
--> Just "[email protected]"


"person@[email protected]"
    |> validate defaultOptions
--> Nothing

Accessors and modifiers

domain : Email -> String

Returns the domain portion of an Email.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map domain
--> Ok "example.org"
local : Email -> String

Returns the local portion of an Email.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map local
--> Ok "person+adult"
plus : Email -> Maybe String

Returns the plus portion of an Email.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map plus
--> Ok (Just "adult")


"[email protected]"
    |> fromString defaultOptions
    |> Result.map plus
--> Ok Nothing
stem : Email -> String

Returns the stem portion of an Email.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map stem
--> Ok "person"

Returns an Email with the plus portion removed.

"[email protected]"
    |> fromString defaultOptions
    |> Result.map removePlus
    |> Result.map toString
--> Ok "[email protected]"

The "empty" email address

An empty email address. Use this if you want an Email instance.

"not@an@email@address"
    |> fromString defaultOptions
    |> Result.withDefault empty
    |> toString
--> ""
isEmpty : Email -> Bool

Test if an Email is the empty email address.

empty |> isEmpty
--> True

Opaque types

type Email

The opaque type representing an email address.