Skip to content

Commit

Permalink
Add a substring modification (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
arieroos authored May 21, 2023
1 parent 0215b84 commit 749a175
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
1 change: 1 addition & 0 deletions modifiers/modifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func New() *mold.Transformer {
mod.Register("strip_num_unicode", stripNumUnicodeCase)
mod.Register("strip_num", stripNumCase)
mod.Register("strip_punctuation", stripPunctuation)
mod.Register("substr", subStr)
mod.Register("title", titleCase)
mod.Register("tprefix", trimPrefix)
mod.Register("trim", trimSpace)
Expand Down
40 changes: 40 additions & 0 deletions modifiers/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"reflect"
"regexp"
"strconv"
"strings"
"unicode"
"unicode/utf8"
Expand Down Expand Up @@ -223,3 +224,42 @@ func camelCase(ctx context.Context, fl mold.FieldLevel) error {
}
return nil
}

func subStr(ctx context.Context, fl mold.FieldLevel) error {
switch fl.Field().Kind() {
case reflect.String:
val := fl.Field().String()
params := strings.SplitN(fl.Param(), "-", 2)
if len(params) == 0 || len(params[0]) == 0 {
return nil
}

start, err := strconv.Atoi(params[0])
if err != nil {
return err
}

end := len(val)
if len(params) >= 2 {
end, err = strconv.Atoi(params[1])
if err != nil {
return err
}
}

if len(val) < start {
fl.Field().SetString("")
return nil
}
if len(val) < end {
end = len(val)
}
if start > end {
fl.Field().SetString("")
return nil
}

fl.Field().SetString(val[start:end])
}
return nil
}
106 changes: 106 additions & 0 deletions modifiers/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,3 +994,109 @@ var (
reflect.TypeOf(sql.NullString{}): true,
}
)

func TestSubStr(t *testing.T) {
conform := New()

s := "123"
expected := "123"

type Test struct {
String string `mod:"substr=0-3"`
}

tt := Test{String: s}
err := conform.Struct(context.Background(), &tt)
if err != nil {
log.Fatal(err)
}
if tt.String != expected {
t.Fatalf("Unexpected value '%s'\n", tt.String)
}

tag := "substr=f-3"
err = conform.Field(context.Background(), &s, tag)
if err == nil {
t.Fatalf("Unexpected value '%s' instead of error for tag %s\n", s, tag)
}
tag = "substr=2-f"
err = conform.Field(context.Background(), &s, tag)
if err == nil {
t.Fatalf("Unexpected value '%s' instead of error for tag %s\n", s, tag)
}

tests := []struct {
tag string
expected string
}{
{
tag: "substr",
expected: "123",
},
{
tag: "substr=0-1",
expected: "1",
},
{
tag: "substr=0-3",
expected: "123",
},
{
tag: "substr=0-2",
expected: "12",
},
{
tag: "substr=1-2",
expected: "2",
},
{
tag: "substr=3-3",
expected: "",
},
{
tag: "substr=4-5",
expected: "",
},
{
tag: "substr=2-1",
expected: "",
},
{
tag: "substr=2-5",
expected: "3",
},
{
tag: "substr=2",
expected: "3",
},
}
for _, test := range tests {
st := s

err = conform.Field(context.Background(), &st, test.tag)
if err != nil {
log.Fatal(err)
}
if st != test.expected {
t.Fatalf("Unexpected value '%s' for tag %s\n", st, test.tag)
}

var iface interface{}
err = conform.Field(context.Background(), &iface, test.tag)
if err != nil {
log.Fatal(err)
}
if iface != nil {
t.Fatalf("Unexpected value '%v'\n", nil)
}

iface = s
err = conform.Field(context.Background(), &iface, test.tag)
if err != nil {
log.Fatal(err)
}
if iface != test.expected {
t.Fatalf("Unexpected value '%v'\n", iface)
}
}
}

0 comments on commit 749a175

Please sign in to comment.