Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ascii tag #12

Merged
merged 1 commit into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ You set the validation rules following the "validate:" tag according to the rule
|-------------------|---------------------------------------------------|
| alpha | Check whether value is alphabetic or not |
| alphanumeric | Check whether value is alphanumeric or not |
| ascii | Check whether value is ASCII or not |
| boolean | Check whether value is boolean or not. |
| lowercase | Check whether value is lowercase or not |
| numeric | Check whether value is numeric or not |
Expand Down
30 changes: 30 additions & 0 deletions csv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package csv

import (
"bytes"
"fmt"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -498,4 +499,33 @@ ABC
}
}
})

t.Run("validate ascii", func(t *testing.T) {
t.Parallel()

input := fmt.Sprintf(
"name\n%s\n%s\n",
"\"!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\`]^_abcdefghijklmnopqrstuvwxyz{|}~\"",
"あいう",
)

c, err := NewCSV(bytes.NewBufferString(input))
if err != nil {
t.Fatal(err)
}
type ascii struct {
Name string `validate:"ascii"`
}

asciis := make([]ascii, 0)
errs := c.Decode(&asciis)
for i, err := range errs {
switch i {
nao1215 marked this conversation as resolved.
Show resolved Hide resolved
case 0:
if err.Error() != "line:3 column name: target is not an ASCII character: value=あいう" {
t.Errorf("CSV.Decode() got errors: %v", err)
}
}
}
})
}
2 changes: 2 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ var (
ErrLowercaseID = "ErrLowercase"
// ErrUppercaseID is the error ID used when the target is not an uppercase character.
ErrUppercaseID = "ErrUppercase"
// ErrASCIIID is the error ID used when the target is not an ASCII character.
ErrASCIIID = "ErrASCII"
)
3 changes: 3 additions & 0 deletions i18n/en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@

- id: "ErrUppercase"
translation: "target is not an uppercase character"

- id: "ErrASCII"
translation: "target is not an ASCII character"
3 changes: 3 additions & 0 deletions i18n/ja.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@

- id: "ErrUppercase"
translation: "値が大文字ではありません"

- id: "ErrASCII"
translation: "値がASCII文字ではありません"
3 changes: 3 additions & 0 deletions i18n/ru.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@

- id: "ErrUppercase"
translation: "целевое значение не является заглавным символом"

- id: "ErrASCII"
translation: "целевое значение не является ASCII символом"
2 changes: 2 additions & 0 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ func (c *CSV) parseValidateTag(tags string) (validators, error) {
validatorList = append(validatorList, newLowercaseValidator())
case strings.HasPrefix(t, uppercaseTagValue.String()):
validatorList = append(validatorList, newUppercaseValidator())
case strings.HasPrefix(t, asciiTagValue.String()):
validatorList = append(validatorList, newASCIIValidator())
}
}
return validatorList, nil
Expand Down
2 changes: 2 additions & 0 deletions tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ const (
lowercaseTagValue tagValue = "lowercase"
// uppercaseTagValue is the struct tag name for uppercase fields.
uppercaseTagValue tagValue = "uppercase"
// asciiTagValue is the struct tag name for ascii fields.
asciiTagValue tagValue = "ascii"
)

// String returns the string representation of the tag.
Expand Down
23 changes: 23 additions & 0 deletions validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,26 @@ func (u *uppercaseValidator) Do(localizer *i18n.Localizer, target any) error {
}
return nil
}

// asciiValidator is a struct that contains the validation rules for an ASCII column.
type asciiValidator struct{}

// newASCIIValidator returns a new asciiValidator.
func newASCIIValidator() *asciiValidator {
return &asciiValidator{}
}

// Do validates the target is an ASCII string.
func (a *asciiValidator) Do(localizer *i18n.Localizer, target any) error {
v, ok := target.(string)
if !ok {
return NewError(localizer, ErrASCIIID, fmt.Sprintf("value=%v", target))
}

for _, r := range v {
if r > 127 {
return NewError(localizer, ErrASCIIID, fmt.Sprintf("value=%v", target))
}
}
return nil
}