package store import ( "fmt" "net/mail" "strings" "unicode/utf8" ) const ( minEmailLen = 3 maxEmailLen = 254 ) // NormalizeEmail trims and lowercases an address for storage/comparison. func NormalizeEmail(s string) string { return strings.ToLower(strings.TrimSpace(s)) } // ValidateEmail returns a normalized address or an error message suitable for UI. func ValidateEmail(raw string) (normalized string, errMsg string) { normalized = NormalizeEmail(raw) if normalized == "" { return "", "Email is required." } n := utf8.RuneCountInString(normalized) if n < minEmailLen || len(normalized) > maxEmailLen { return "", "Enter a valid email address." } addr, err := mail.ParseAddress(normalized) if err != nil || addr.Address != normalized { return "", "Enter a valid email address." } at := strings.LastIndex(normalized, "@") if at < 1 || at == len(normalized)-1 { return "", "Enter a valid email address." } domain := normalized[at+1:] if !strings.Contains(domain, ".") || strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") { return "", "Enter a valid email address." } return normalized, "" } // MustValidateEmail is like ValidateEmail but returns a Go error. func MustValidateEmail(raw string) (string, error) { n, msg := ValidateEmail(raw) if msg != "" { return "", fmt.Errorf("%s", msg) } return n, nil }