diff --git a/README.md b/README.md index 20c7f73..52a9f1d 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ type Person struct { This package currently provides the following checkers: +- [alphanumeric](doc/checkers/alphanumeric.md) checks if the given string consists of only alphanumeric characters. - [ascii](doc/checkers/ascii.md) checks if the given string consists of only ASCII characters. - [digits](doc/checkers/digits.md) checks if the given string consists of only digit characters. - [max](doc/checkers/max.md) checks if the given value is less than the given maximum. diff --git a/alphanumeric.go b/alphanumeric.go new file mode 100644 index 0000000..bea70d4 --- /dev/null +++ b/alphanumeric.go @@ -0,0 +1,37 @@ +package checker + +import ( + "reflect" + "unicode" +) + +// CheckerAlphanumeric is the name of the checker. +const CheckerAlphanumeric = "alphanumeric" + +// ResultNotAlphanumeric indicates that the given string contains non-alphanumeric characters. +const ResultNotAlphanumeric = "NOT_ALPHANUMERIC" + +// IsAlphanumeric checks if the given string consists of only alphanumeric characters. +func IsAlphanumeric(value string) Result { + for _, c := range value { + if !unicode.IsDigit(c) && !unicode.IsLetter(c) { + return ResultNotAlphanumeric + } + } + + return ResultValid +} + +// makeAlphanumeric makes a checker function for the alphanumeric checker. +func makeAlphanumeric(_ string) CheckFunc { + return checkAlphanumeric +} + +// checkAlphanumeric checks if the given string consists of only alphanumeric characters. +func checkAlphanumeric(value, _ reflect.Value) Result { + if value.Kind() != reflect.String { + panic("string expected") + } + + return IsAlphanumeric(value.String()) +} diff --git a/alphanumeric_test.go b/alphanumeric_test.go new file mode 100644 index 0000000..82ee9c4 --- /dev/null +++ b/alphanumeric_test.go @@ -0,0 +1,57 @@ +package checker + +import "testing" + +func TestIsAlphanumericInvalid(t *testing.T) { + if IsAlphanumeric("-/") == ResultValid { + t.Fail() + } +} + +func TestIsAlphanumericValid(t *testing.T) { + if IsAlphanumeric("ABcd1234") != ResultValid { + t.Fail() + } +} + +func TestCheckAlphanumericNonString(t *testing.T) { + defer FailIfNoPanic(t) + + type User struct { + Username int `checkers:"alphanumeric"` + } + + user := &User{} + + Check(user) +} + +func TestCheckAlphanumericInvalid(t *testing.T) { + type User struct { + Username string `checkers:"alphanumeric"` + } + + user := &User{ + Username: "user-/", + } + + _, valid := Check(user) + if valid { + t.Fail() + } +} + +func TestCheckAlphanumericValid(t *testing.T) { + type User struct { + Username string `checkers:"alphanumeric"` + } + + user := &User{ + Username: "ABcd1234", + } + + _, valid := Check(user) + if !valid { + t.Fail() + } +} diff --git a/ascii.go b/ascii.go index c6c0523..f41faa3 100644 --- a/ascii.go +++ b/ascii.go @@ -13,8 +13,8 @@ const ResultNotAscii = "NOT_ASCII" // IsAscii checks if the given string consists of only ASCII characters. func IsAscii(value string) Result { - for i := 0; i < len(value); i++ { - if value[i] > unicode.MaxASCII { + for _, c := range value { + if c > unicode.MaxASCII { return ResultNotAscii } } diff --git a/checker.go b/checker.go index d298934..e2e23f3 100644 --- a/checker.go +++ b/checker.go @@ -31,14 +31,15 @@ const ResultValid Result = "VALID" // makers provides mapping to maker function for the checkers. var makers = map[string]MakeFunc{ - CheckerAscii: makeAscii, - CheckerDigits: makeDigits, - CheckerMax: makeMax, - CheckerMaxLength: makeMaxLength, - CheckerMin: makeMin, - CheckerMinLength: makeMinLength, - CheckerRequired: makeRequired, - CheckerSame: makeSame, + CheckerAlphanumeric: makeAlphanumeric, + CheckerAscii: makeAscii, + CheckerDigits: makeDigits, + CheckerMax: makeMax, + CheckerMaxLength: makeMaxLength, + CheckerMin: makeMin, + CheckerMinLength: makeMinLength, + CheckerRequired: makeRequired, + CheckerSame: makeSame, } // Register registers the given checker name and the maker function. diff --git a/digits.go b/digits.go index 4ab56ac..ee16598 100644 --- a/digits.go +++ b/digits.go @@ -2,6 +2,7 @@ package checker import ( "reflect" + "unicode" ) // CheckerDigits is the name of the checker. @@ -12,8 +13,8 @@ const ResultNotDigits = "NOT_DIGITS" // IsDigits checks if the given string consists of only digit characters. func IsDigits(value string) Result { - for i := 0; i < len(value); i++ { - if value[i] < '0' || value[i] > '9' { + for _, c := range value { + if !unicode.IsDigit(c) { return ResultNotDigits } } diff --git a/doc/checkers/alphanumeric.md b/doc/checkers/alphanumeric.md new file mode 100644 index 0000000..2cb89b6 --- /dev/null +++ b/doc/checkers/alphanumeric.md @@ -0,0 +1,28 @@ +# Alphanumeric Checker + +The ```alphanumeric``` checker checks if the given string consists of only alphanumeric characters. If the string contains non-alphanumeric characters, the checker will return the ```NOT_ALPHANUMERIC``` result. Here is an example: + +```golang +type User struct { + Username string `checkers:"alphanumeric"` +} + +user := &User{ + Username: "ABcd1234", +} + +_, valid := Check(user) +if !valid { + // Send the mistakes back to the user +} +``` + +In your custom checkers, you can call the ```alphanumeric``` checker function ```IsAlphanumeric``` to validate the user input. Here is an example: + +```golang +result := IsAlphanumeric("ABcd1234") + +if result != ResultValid { + // Send the mistakes back to the user +} +```