Skip to content

Commit 749a175

Browse files
authored
Add a substring modification (#36)
1 parent 0215b84 commit 749a175

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

modifiers/modifiers.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ func New() *mold.Transformer {
2222
mod.Register("strip_num_unicode", stripNumUnicodeCase)
2323
mod.Register("strip_num", stripNumCase)
2424
mod.Register("strip_punctuation", stripPunctuation)
25+
mod.Register("substr", subStr)
2526
mod.Register("title", titleCase)
2627
mod.Register("tprefix", trimPrefix)
2728
mod.Register("trim", trimSpace)

modifiers/string.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"reflect"
77
"regexp"
8+
"strconv"
89
"strings"
910
"unicode"
1011
"unicode/utf8"
@@ -223,3 +224,42 @@ func camelCase(ctx context.Context, fl mold.FieldLevel) error {
223224
}
224225
return nil
225226
}
227+
228+
func subStr(ctx context.Context, fl mold.FieldLevel) error {
229+
switch fl.Field().Kind() {
230+
case reflect.String:
231+
val := fl.Field().String()
232+
params := strings.SplitN(fl.Param(), "-", 2)
233+
if len(params) == 0 || len(params[0]) == 0 {
234+
return nil
235+
}
236+
237+
start, err := strconv.Atoi(params[0])
238+
if err != nil {
239+
return err
240+
}
241+
242+
end := len(val)
243+
if len(params) >= 2 {
244+
end, err = strconv.Atoi(params[1])
245+
if err != nil {
246+
return err
247+
}
248+
}
249+
250+
if len(val) < start {
251+
fl.Field().SetString("")
252+
return nil
253+
}
254+
if len(val) < end {
255+
end = len(val)
256+
}
257+
if start > end {
258+
fl.Field().SetString("")
259+
return nil
260+
}
261+
262+
fl.Field().SetString(val[start:end])
263+
}
264+
return nil
265+
}

modifiers/string_test.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,3 +994,109 @@ var (
994994
reflect.TypeOf(sql.NullString{}): true,
995995
}
996996
)
997+
998+
func TestSubStr(t *testing.T) {
999+
conform := New()
1000+
1001+
s := "123"
1002+
expected := "123"
1003+
1004+
type Test struct {
1005+
String string `mod:"substr=0-3"`
1006+
}
1007+
1008+
tt := Test{String: s}
1009+
err := conform.Struct(context.Background(), &tt)
1010+
if err != nil {
1011+
log.Fatal(err)
1012+
}
1013+
if tt.String != expected {
1014+
t.Fatalf("Unexpected value '%s'\n", tt.String)
1015+
}
1016+
1017+
tag := "substr=f-3"
1018+
err = conform.Field(context.Background(), &s, tag)
1019+
if err == nil {
1020+
t.Fatalf("Unexpected value '%s' instead of error for tag %s\n", s, tag)
1021+
}
1022+
tag = "substr=2-f"
1023+
err = conform.Field(context.Background(), &s, tag)
1024+
if err == nil {
1025+
t.Fatalf("Unexpected value '%s' instead of error for tag %s\n", s, tag)
1026+
}
1027+
1028+
tests := []struct {
1029+
tag string
1030+
expected string
1031+
}{
1032+
{
1033+
tag: "substr",
1034+
expected: "123",
1035+
},
1036+
{
1037+
tag: "substr=0-1",
1038+
expected: "1",
1039+
},
1040+
{
1041+
tag: "substr=0-3",
1042+
expected: "123",
1043+
},
1044+
{
1045+
tag: "substr=0-2",
1046+
expected: "12",
1047+
},
1048+
{
1049+
tag: "substr=1-2",
1050+
expected: "2",
1051+
},
1052+
{
1053+
tag: "substr=3-3",
1054+
expected: "",
1055+
},
1056+
{
1057+
tag: "substr=4-5",
1058+
expected: "",
1059+
},
1060+
{
1061+
tag: "substr=2-1",
1062+
expected: "",
1063+
},
1064+
{
1065+
tag: "substr=2-5",
1066+
expected: "3",
1067+
},
1068+
{
1069+
tag: "substr=2",
1070+
expected: "3",
1071+
},
1072+
}
1073+
for _, test := range tests {
1074+
st := s
1075+
1076+
err = conform.Field(context.Background(), &st, test.tag)
1077+
if err != nil {
1078+
log.Fatal(err)
1079+
}
1080+
if st != test.expected {
1081+
t.Fatalf("Unexpected value '%s' for tag %s\n", st, test.tag)
1082+
}
1083+
1084+
var iface interface{}
1085+
err = conform.Field(context.Background(), &iface, test.tag)
1086+
if err != nil {
1087+
log.Fatal(err)
1088+
}
1089+
if iface != nil {
1090+
t.Fatalf("Unexpected value '%v'\n", nil)
1091+
}
1092+
1093+
iface = s
1094+
err = conform.Field(context.Background(), &iface, test.tag)
1095+
if err != nil {
1096+
log.Fatal(err)
1097+
}
1098+
if iface != test.expected {
1099+
t.Fatalf("Unexpected value '%v'\n", iface)
1100+
}
1101+
}
1102+
}

0 commit comments

Comments
 (0)