github.com/go-email-validator/go-email-validator@v0.0.0-20230409163946-b8b9e6a0552e/pkg/presentation/as-email-verifier/dep.go (about) 1 package asemailverifier 2 3 import ( 4 "github.com/go-email-validator/go-email-validator/pkg/ev" 5 "github.com/go-email-validator/go-email-validator/pkg/ev/evmail" 6 "github.com/go-email-validator/go-email-validator/pkg/presentation/converter" 7 "regexp" 8 ) 9 10 const ( 11 // Name of https://github.com/AfterShip/email-verifier converter 12 Name converter.Name = "AfterShipEmailVerifier" 13 14 // EmailRegexString is an email regex 15 EmailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" 16 ) 17 18 // DepPresentation is a presentation 19 type DepPresentation struct { 20 Email string `json:"email"` 21 Reachable Reachable `json:"reachable"` 22 Syntax *SyntaxPresentation `json:"syntax"` 23 SMTP *SMTPPresentation `json:"smtp"` 24 Gravatar *GravatarPresentation `json:"gravatar"` 25 Suggestion string `json:"suggestion"` 26 Disposable bool `json:"disposable"` 27 RoleAccount bool `json:"role_account"` 28 Free bool `json:"free"` 29 HasMxRecords bool `json:"has_mx_records"` 30 } 31 32 // DepConverter converts ev.ValidationResult in DepPresentation 33 type DepConverter struct { 34 converter converter.CompositeConverter 35 calculateReachable FuncReachable 36 } 37 38 // NewDepConverterDefault creates default DepConverter 39 func NewDepConverterDefault() DepConverter { 40 return NewDepConverter( 41 converter.NewCompositeConverter(converter.MapConverters{ 42 ev.SMTPValidatorName: converter.NewSMTPConverter(), 43 ev.SyntaxValidatorName: SyntaxConverter{}, 44 ev.GravatarValidatorName: GravatarConverter{}, 45 }), 46 CalculateReachable, 47 ) 48 } 49 50 // NewDepConverter creates DepConverter 51 func NewDepConverter(converter converter.CompositeConverter, calculateReachable FuncReachable) DepConverter { 52 return DepConverter{converter, calculateReachable} 53 } 54 55 // Can ev.ValidationResult be converted in DepConverter 56 func (DepConverter) Can(_ evmail.Address, result ev.ValidationResult, _ converter.Options) bool { 57 return result.ValidatorName() == ev.DepValidatorName 58 } 59 60 // Convert ev.ValidationResult in DepConverter 61 func (s DepConverter) Convert(email evmail.Address, resultInterface ev.ValidationResult, opts converter.Options) interface{} { 62 depResult := resultInterface.(ev.DepValidationResult) 63 validationResults := depResult.GetResults() 64 65 var syntax *SyntaxPresentation 66 var smtp *SMTPPresentation 67 var gravatar *GravatarPresentation 68 mxResult := validationResults[ev.MXValidatorName].(ev.MXValidationResult) 69 for _, validatorResult := range depResult.GetResults() { 70 if !s.converter.Can(email, validatorResult, opts) { 71 continue 72 } 73 74 switch v := s.converter.Convert(email, validatorResult, opts).(type) { 75 case *SyntaxPresentation: 76 syntax = v 77 case converter.SMTPPresentation: 78 smtp = &SMTPPresentation{ 79 HostExists: v.CanConnectSMTP, 80 FullInbox: v.HasFullInbox, 81 CatchAll: v.IsCatchAll, 82 Deliverable: !v.IsCatchAll && v.IsDeliverable, 83 Disabled: v.IsDisabled, 84 } 85 case *GravatarPresentation: 86 gravatar = v 87 } 88 } 89 90 depPresentation := DepPresentation{ 91 Email: email.String(), 92 Reachable: ReachableUnknown, 93 Syntax: syntax, 94 } 95 96 if syntax == nil || !syntax.Valid { 97 return depPresentation 98 } 99 100 depPresentation.Free = !validationResults[ev.FreeValidatorName].IsValid() 101 depPresentation.RoleAccount = !validationResults[ev.RoleValidatorName].IsValid() 102 depPresentation.Disposable = !validationResults[ev.DisposableValidatorName].IsValid() 103 104 if depPresentation.Disposable { 105 return depPresentation 106 } 107 108 if !mxResult.IsValid() { 109 return depPresentation 110 } 111 112 depPresentation.HasMxRecords = len(mxResult.MX()) > 0 113 114 if smtp == nil || !smtp.HostExists { 115 return depPresentation 116 } 117 118 depPresentation.SMTP = smtp 119 depPresentation.Reachable = s.calculateReachable(depPresentation) 120 121 if gravatar != nil { 122 depPresentation.Gravatar = gravatar 123 } 124 125 return depPresentation 126 } 127 128 // NewDepValidator is a default validator 129 func NewDepValidator(smtpValidator ev.Validator) ev.Validator { 130 builder := ev.NewDepBuilder(nil) 131 if smtpValidator == nil { 132 smtpValidator = builder.Get(ev.SMTPValidatorName) 133 } 134 135 return ev.NewDepBuilder(nil).Set( 136 ev.SyntaxValidatorName, 137 ev.NewSyntaxRegexValidator(regexp.MustCompile(EmailRegexString)), 138 ). 139 Set(ev.GravatarValidatorName, ev.NewGravatarValidator()). 140 Set(ev.SMTPValidatorName, smtpValidator). 141 Set(ev.FreeValidatorName, ev.FreeDefaultValidator()). 142 Build() 143 }