Documentation
¶
Overview ¶
Package email validates email addresses against the IETF specifications that define them.
An address is checked against the Mailbox production of RFC 5321 (Simple Mail Transfer Protocol), section 4.1.2, which is the grammar an address must satisfy to be usable in a MAIL or RCPT command:
Mailbox = Local-part "@" ( Domain / address-literal ) Local-part = Dot-string / Quoted-string
Length limits come from RFC 5321 section 4.5.3.1 (64-octet local part, 255-octet domain, 256-octet path) as clarified by RFC 3696 erratum 1690: an address can be at most 254 octets. Domain labels are limited to 63 octets per RFC 1035.
ValidateSMTPUTF8 additionally applies the internationalization extensions of RFC 6531 and RFC 6532, which extend atext and qtextSMTP with well-formed non-ASCII UTF-8 and permit IDNA2008 U-labels in the domain.
RFC 5322's addr-spec features that exist only for message framing (comments, folding white space, obsolete syntax) are intentionally not accepted: they are not part of a mailbox address, and RFC 5322 itself says they SHOULD NOT be used in addr-spec.
Each validation failure is reported as a *SyntaxError, which records the byte offset of the fault and wraps one of the package's sentinel errors, so callers can classify failures with errors.Is. All functions are safe for concurrent use.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrEmptyAddress = errors.New("email address is empty") ErrAddressTooLong = errors.New("email address exceeds 254 octets (RFC 5321 4.5.3.1.3, RFC 3696 erratum 1690)") ErrMissingAtSign = errors.New(`email address has no "@" separating local part and domain`) ErrLocalPartTooLong = errors.New("local part exceeds 64 octets (RFC 5321 4.5.3.1.1)") ErrInvalidLocalPart = errors.New("invalid local part") ErrInvalidDomain = errors.New("invalid domain") )
Errors reported by Validate and ValidateSMTPUTF8. Errors returned by this package wrap one of these sentinels, so callers can classify failures with errors.Is.
Functions ¶
func IsValid ¶
IsValid reports whether addr is valid per RFC 5321.
Example ¶
package main
import (
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
fmt.Println(email.IsValid("ada@example.com"))
fmt.Println(email.IsValid("ada@@example.com"))
}
Output: true false
func IsValidSMTPUTF8 ¶
IsValidSMTPUTF8 reports whether addr is valid per RFC 6531.
Example ¶
package main
import (
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
fmt.Println(email.IsValidSMTPUTF8("用户@example.com"))
fmt.Println(email.IsValidSMTPUTF8("用户@exa_mple.com"))
}
Output: true false
func Validate ¶
Validate reports whether addr is a syntactically valid email address per RFC 5321 (ASCII only). It returns nil for a valid address and a *SyntaxError wrapping one of this package's sentinel errors otherwise.
Example ¶
package main
import (
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
err := email.Validate("grace.hopper@example.com")
fmt.Println(err)
}
Output: <nil>
Example (Invalid) ¶
package main
import (
"errors"
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
err := email.Validate("grace..hopper@example.com")
fmt.Println(err)
fmt.Println(errors.Is(err, email.ErrInvalidLocalPart))
}
Output: invalid local part: local part may not contain consecutive dots true
func ValidateSMTPUTF8 ¶
ValidateSMTPUTF8 is like Validate but additionally accepts internationalized addresses per RFC 6531/6532 (SMTPUTF8): well-formed non-ASCII UTF-8 is permitted in the local part, and non-ASCII domain labels must be valid IDNA2008 U-labels.
Callers accepting user-entered domains should apply any desired IDNA mapping and normalization before constructing addr. ValidateSMTPUTF8 validates the supplied address but does not rewrite it.
Example ¶
package main
import (
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
addr := "用户@例子.example"
fmt.Println(email.Validate(addr) == nil)
fmt.Println(email.ValidateSMTPUTF8(addr) == nil)
}
Output: false true
Types ¶
type SyntaxError ¶
type SyntaxError struct {
Addr string // the address passed to Validate or ValidateSMTPUTF8
Offset int // byte offset in Addr at which the fault was detected
Err error // sentinel classification: ErrInvalidLocalPart, ErrInvalidDomain, ...
Detail string // description of the fault; may be empty
}
A SyntaxError describes why an email address failed validation and where the fault was detected. Every non-nil error returned by Validate and ValidateSMTPUTF8 is a *SyntaxError.
Err is one of this package's sentinel errors and is returned by Unwrap, so errors.Is(err, ErrInvalidDomain) and similar classifications work on a *SyntaxError.
Offset is a byte offset into Addr: the offending byte where one is known, otherwise the start of the offending component. For an invalid internationalized (IDNA) domain label, Offset is the start of that label.
Example ¶
package main
import (
"errors"
"fmt"
email "github.com/initialcapacity/email-address-validator"
)
func main() {
err := email.Validate("ada@exa_mple.com")
var syntaxErr *email.SyntaxError
if errors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset)
fmt.Println(errors.Is(err, email.ErrInvalidDomain))
}
}
Output: 7 true
func (*SyntaxError) Error ¶
func (e *SyntaxError) Error() string
func (*SyntaxError) Unwrap ¶
func (e *SyntaxError) Unwrap() error