diff --git a/v2/hex.go b/v2/hex.go new file mode 100644 index 0000000..0b6144d --- /dev/null +++ b/v2/hex.go @@ -0,0 +1,36 @@ +// 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 ( + "reflect" +) + +const ( + // nameHex is the name of the hex check. + nameHex = "hex" +) + +var ( + // ErrNotHex indicates that the given string contains hex characters. + ErrNotHex = NewCheckError("HEX") +) + +// IsHex checks if the given string consists of only hex characters. +func IsHex(value string) (string, error) { + return IsRegexp("^[0-9a-fA-F]+$", value) +} + +// isHex checks if the given string consists of only hex characters. +func isHex(value reflect.Value) (reflect.Value, error) { + _, err := IsHex(value.Interface().(string)) + return value, err +} + +// makeAlphanumeric makes a checker function for the alphanumeric checker. +func makeHex(_ string) CheckFunc[reflect.Value] { + return isHex +} diff --git a/v2/hex_test.go b/v2/hex_test.go new file mode 100644 index 0000000..304d777 --- /dev/null +++ b/v2/hex_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 ExampleIsHex() { + _, err := v2.IsHex("0123456789abcdefABCDEF") + if err != nil { + fmt.Println(err) + } +} + +func TestIsHexInvalid(t *testing.T) { + _, err := v2.IsHex("ONUR") + if err == nil { + t.Fatal("expected error") + } +} + +func TestIsHexValid(t *testing.T) { + _, err := v2.IsHex("0123456789abcdefABCDEF") + if err != nil { + t.Fatal(err) + } +} + +func TestCheckHexNonString(t *testing.T) { + defer FailIfNoPanic(t, "expected panic") + + type Car struct { + Color int `checkers:"hex"` + } + + car := &Car{} + + v2.CheckStruct(car) +} + +func TestCheckHexInvalid(t *testing.T) { + type Car struct { + Color string `checkers:"hex"` + } + + car := &Car{ + Color: "red", + } + + _, ok := v2.CheckStruct(car) + if ok { + t.Fatal("expected error") + } +} + +func TestCheckHexValid(t *testing.T) { + type Car struct { + Color string `checkers:"hex"` + } + + car := &Car{ + Color: "ABcd1234", + } + + errs, ok := v2.CheckStruct(car) + if !ok { + t.Fatal(errs) + } +} diff --git a/v2/luhn_test.go b/v2/luhn_test.go index 7831ccc..877d5c5 100644 --- a/v2/luhn_test.go +++ b/v2/luhn_test.go @@ -26,6 +26,13 @@ func TestIsLUHNInvalid(t *testing.T) { } } +func TestIsLUHNInvalidDigits(t *testing.T) { + _, err := v2.IsLUHN("ABCD") + if err == nil { + t.Fatal("expected error") + } +} + func TestIsLUHNValid(t *testing.T) { _, err := v2.IsLUHN("4012888888881881") if err != nil { diff --git a/v2/maker.go b/v2/maker.go index 81866db..935d04b 100644 --- a/v2/maker.go +++ b/v2/maker.go @@ -23,6 +23,7 @@ var makers = map[string]MakeCheckFunc{ nameDigits: makeDigits, nameEmail: makeEmail, nameFQDN: makeFQDN, + nameHex: makeHex, nameHTMLEscape: makeHTMLEscape, nameHTMLUnescape: makeHTMLUnescape, nameIP: makeIP, diff --git a/v2/regexp.go b/v2/regexp.go index 426a6dd..8ae5663 100644 --- a/v2/regexp.go +++ b/v2/regexp.go @@ -16,6 +16,15 @@ const nameRegexp = "regexp" // ErrNotMatch indicates that the given string does not match the regexp pattern. var ErrNotMatch = NewCheckError("REGEXP") +// IsRegexp checks if the given string matches the given regexp expression. +func IsRegexp(expression, value string) (string, error) { + if !regexp.MustCompile(expression).MatchString(value) { + return value, ErrNotMatch + } + + return value, nil +} + // MakeRegexpChecker makes a regexp checker for the given regexp expression with the given invalid result. func MakeRegexpChecker(expression string, invalidError error) CheckFunc[reflect.Value] { return func(value reflect.Value) (reflect.Value, error) { @@ -23,12 +32,8 @@ func MakeRegexpChecker(expression string, invalidError error) CheckFunc[reflect. panic("string expected") } - matched, err := regexp.MatchString(expression, value.String()) + _, err := IsRegexp(expression, value.String()) if err != nil { - return value, err - } - - if !matched { return value, invalidError } @@ -40,8 +45,3 @@ func MakeRegexpChecker(expression string, invalidError error) CheckFunc[reflect. func makeRegexp(config string) CheckFunc[reflect.Value] { return MakeRegexpChecker(config, ErrNotMatch) } - -// checkRegexp checks if the given string matches the regexp pattern. -func checkRegexp(value reflect.Value) (reflect.Value, error) { - return makeRegexp(value.String())(value) -} diff --git a/v2/regexp_test.go b/v2/regexp_test.go index e66a760..cdb78dd 100644 --- a/v2/regexp_test.go +++ b/v2/regexp_test.go @@ -6,12 +6,33 @@ package v2_test import ( - "reflect" + "fmt" "testing" v2 "github.com/cinar/checker/v2" ) +func ExampleIsRegexp() { + _, err := v2.IsRegexp("^[0-9a-fA-F]+$", "ABcd1234") + if err != nil { + fmt.Println(err) + } +} + +func TestIsRegexpInvalid(t *testing.T) { + _, err := v2.IsRegexp("^[0-9a-fA-F]+$", "Onur") + if err == nil { + t.Fatal("expected error") + } +} + +func TestIsRegexpValid(t *testing.T) { + _, err := v2.IsRegexp("^[0-9a-fA-F]+$", "ABcd1234") + if err != nil { + t.Fatal(err) + } +} + func TestCheckRegexpNonString(t *testing.T) { defer FailIfNoPanic(t, "expected panic") @@ -53,12 +74,3 @@ func TestCheckRegexpValid(t *testing.T) { t.Fatal("expected valid") } } - -func TestMakeRegexpChecker(t *testing.T) { - checkHex := v2.MakeRegexpChecker("^[A-Fa-f0-9]+$", v2.ErrNotMatch) - - _, err := checkHex(reflect.ValueOf("f0f0f0")) - if err != nil { - t.Fail() - } -}