diff --git a/v2/email.go b/v2/email.go new file mode 100644 index 0000000..7251850 --- /dev/null +++ b/v2/email.go @@ -0,0 +1,41 @@ +// Copyright (c) 2023-2024 Onur Cinar. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. +// https://github.com/cinar/checker + +package v2 + +import ( + "net/mail" + "reflect" +) + +const ( + // nameEmail is the name of the email check. + nameEmail = "email" +) + +var ( + // ErrNotEmail indicates that the given value is not a valid email address. + ErrNotEmail = NewCheckError("Email") +) + +// IsEmail checks if the value is a valid email address. +func IsEmail(value string) (string, error) { + _, err := mail.ParseAddress(value) + if err != nil { + return value, ErrNotEmail + } + return value, nil +} + +// checkEmail checks if the value is a valid email address. +func checkEmail(value reflect.Value) (reflect.Value, error) { + _, err := IsEmail(value.Interface().(string)) + return value, err +} + +// makeEmail makes a checker function for the email checker. +func makeEmail(_ string) CheckFunc[reflect.Value] { + return checkEmail +} diff --git a/v2/email_test.go b/v2/email_test.go new file mode 100644 index 0000000..20e3665 --- /dev/null +++ b/v2/email_test.go @@ -0,0 +1,76 @@ +// Copyright (c) 2023-2024 Onur Cinar. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. +// https://github.com/cinar/checker + +package v2_test + +import ( + "fmt" + "testing" + + v2 "github.com/cinar/checker/v2" +) + +func ExampleIsEmail() { + _, err := v2.IsEmail("test@example.com") + if err != nil { + fmt.Println(err) + } +} + +func TestIsEmailInvalid(t *testing.T) { + _, err := v2.IsEmail("invalid-email") + if err == nil { + t.Fatal("expected error") + } +} + +func TestIsEmailValid(t *testing.T) { + _, err := v2.IsEmail("test@example.com") + if err != nil { + t.Fatal(err) + } +} + +func TestCheckEmailNonString(t *testing.T) { + defer FailIfNoPanic(t, "expected panic") + + type User struct { + Email int `checkers:"email"` + } + + user := &User{} + + v2.CheckStruct(user) +} + +func TestCheckEmailInvalid(t *testing.T) { + type User struct { + Email string `checkers:"email"` + } + + user := &User{ + Email: "invalid-email", + } + + _, ok := v2.CheckStruct(user) + if ok { + t.Fatal("expected error") + } +} + +func TestCheckEmailValid(t *testing.T) { + type User struct { + Email string `checkers:"email"` + } + + user := &User{ + Email: "test@example.com", + } + + _, ok := v2.CheckStruct(user) + if !ok { + t.Fatal("expected valid") + } +} diff --git a/v2/maker.go b/v2/maker.go index 6806ed3..6841aea 100644 --- a/v2/maker.go +++ b/v2/maker.go @@ -20,6 +20,7 @@ var makers = map[string]MakeCheckFunc{ nameASCII: makeASCII, nameCIDR: makeCIDR, nameDigits: makeDigits, + nameEmail: makeEmail, nameMaxLen: makeMaxLen, nameMinLen: makeMinLen, nameRequired: makeRequired,