schema/field: add rune length validators for string fields (#4398)

Signed-off-by: liangminhua <ben302010@live.cn>
This commit is contained in:
liangminhua
2025-06-20 14:42:13 +08:00
committed by GitHub
parent 09fd57eb3e
commit 86238d83fc
2 changed files with 66 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ import (
"regexp"
"strings"
"time"
"unicode/utf8"
"entgo.io/ent/schema"
)
@@ -222,6 +223,18 @@ func (b *stringBuilder) MinLen(i int) *stringBuilder {
return b
}
// MinRuneLen adds a rune length validator for this field.
// Operation fails if the rune count of the string is less than the given value.
func (b *stringBuilder) MinRuneLen(i int) *stringBuilder {
b.desc.Validators = append(b.desc.Validators, func(v string) error {
if utf8.RuneCountInString(v) < i {
return errors.New("value is less than the required rune length")
}
return nil
})
return b
}
// NotEmpty adds a length validator for this field.
// Operation fails if the length of the string is zero.
func (b *stringBuilder) NotEmpty() *stringBuilder {
@@ -241,6 +254,19 @@ func (b *stringBuilder) MaxLen(i int) *stringBuilder {
return b
}
// MaxRuneLen adds a rune length validator for this field.
// Operation fails if the rune count of the string is greater than the given value.
func (b *stringBuilder) MaxRuneLen(i int) *stringBuilder {
b.desc.Size = i
b.desc.Validators = append(b.desc.Validators, func(v string) error {
if utf8.RuneCountInString(v) > i {
return errors.New("value is greater than the required rune length")
}
return nil
})
return b
}
// Validate adds a validator for this field. Operation fails if the validation fails.
func (b *stringBuilder) Validate(fn func(string) error) *stringBuilder {
b.desc.Validators = append(b.desc.Validators, fn)

View File

@@ -975,3 +975,43 @@ func TestTypeConstName(t *testing.T) {
typ = 21
assert.Equal(t, "invalid", typ.ConstName())
}
func TestString_MinRuneLen(t *testing.T) {
fd := field.String("name").MinRuneLen(5).Descriptor()
assert.Len(t, fd.Validators, 1)
err := fd.Validators[0].(func(string) error)("hello")
assert.NoError(t, err)
err = fd.Validators[0].(func(string) error)("hi")
assert.EqualError(t, err, "value is less than the required rune length")
err = fd.Validators[0].(func(string) error)("你好")
assert.EqualError(t, err, "value is less than the required rune length")
err = fd.Validators[0].(func(string) error)("你好世界!")
assert.NoError(t, err)
err = fd.Validators[0].(func(string) error)("")
assert.Error(t, err)
}
func TestString_MaxRuneLen(t *testing.T) {
fd := field.String("name").MaxRuneLen(5).Descriptor()
assert.Len(t, fd.Validators, 1)
err := fd.Validators[0].(func(string) error)("hello")
assert.NoError(t, err)
err = fd.Validators[0].(func(string) error)("hello world")
assert.EqualError(t, err, "value is greater than the required rune length")
err = fd.Validators[0].(func(string) error)("你好世界你好")
assert.EqualError(t, err, "value is greater than the required rune length")
err = fd.Validators[0].(func(string) error)("你好世界!")
assert.NoError(t, err)
err = fd.Validators[0].(func(string) error)("")
assert.NoError(t, err)
}