feat: add form

This commit is contained in:
lab
2021-12-28 01:49:22 +08:00
parent 5667d34e59
commit 68ee747b7a
7 changed files with 262 additions and 5 deletions

View File

@@ -0,0 +1,22 @@
package form
import (
"context"
"github.com/go-playground/mold/v4"
"github.com/go-playground/mold/v4/modifiers"
)
var conform = NewConform()
func NewConform() *mold.Transformer {
return modifiers.New()
}
func ConformStruct(v interface{}) error {
return ConformStructWithContext(context.TODO(), v)
}
func ConformStructWithContext(ctx context.Context, v interface{}) error {
return conform.Struct(ctx, v)
}

View File

@@ -0,0 +1,28 @@
package form
import (
"net/url"
"github.com/go-playground/form/v4"
)
var (
decoder = NewDecoder()
encoder = NewEncoder()
)
func NewDecoder() *form.Decoder {
return form.NewDecoder()
}
func Decode(values url.Values, v interface{}) error {
return decoder.Decode(v, values)
}
func NewEncoder() *form.Encoder {
return form.NewEncoder()
}
func Encode(v interface{}) (values url.Values, err error) {
return encoder.Encode(v)
}

29
internal/pkg/form/form.go Normal file
View File

@@ -0,0 +1,29 @@
package form
import "net/url"
func SafeQuery(values url.Values, v interface{}) error {
if err := Decode(values, v); err != nil {
return err
}
if err := ConformStruct(v); err != nil {
return err
}
if err := ValidateStruct(v); err != nil {
return err
}
return nil
}
func SafeStruct(v interface{}) error {
if err := ConformStruct(v); err != nil {
return err
}
if err := ValidateStruct(v); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,24 @@
package form
import (
"context"
"github.com/go-playground/mold/v4"
"github.com/go-playground/mold/v4/scrubbers"
)
var (
scrub = NewScrubbers()
)
func NewScrubbers() *mold.Transformer {
return scrubbers.New()
}
func ScrubStruct(v interface{}) error {
return ScrubStructWithContext(context.TODO(), v)
}
func ScrubStructWithContext(ctx context.Context, v interface{}) error {
return scrub.Struct(ctx, v)
}

View File

@@ -0,0 +1,121 @@
package form
import (
"fmt"
"reflect"
"strings"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
zhtrans "github.com/go-playground/validator/v10/translations/zh"
// entrans "github.com/go-playground/validator/v10/translations/en"
)
var (
translator = NewValidateTranslator()
validate = NewValidate()
)
type FieldError struct {
Field string `json:"field"`
Error string `json:"error"`
Value string `json:"value"`
Raw validator.FieldError `json:"-"`
}
func (err FieldError) String() string {
return fmt.Sprintf("%s:%s", err.Field, err.Error)
}
type FieldsError []*FieldError
func (errs FieldsError) Error() string {
var msg []string
for _, err := range errs {
msg = append(msg, err.String())
}
return strings.Join(msg, ";")
}
func init() {
// en := en.New() //英文翻译器
// zh := zh.New() //中文翻译器
// // 第一个参数是必填,如果没有其他的语言设置,就用这第一个
// // 后面的参数是支持多语言环境(
// // uni := ut.New(en, en) 也是可以的
// // uni := ut.New(en, zh, tw)
// uni := ut.New(en, zh)
// translator, ok := uni.GetTranslator("zh") //获取需要的语言
// if !ok {
// panic("translator not found")
// }
// validate := validator.New()
// validate.RegisterTagNameFunc(func(field reflect.StructField) string {
// label := field.Tag.Get("label")
// if label == "" {
// return field.Name
// }
// return label
// })
zhtrans.RegisterDefaultTranslations(validate, translator)
}
func NewValidateTranslator() ut.Translator {
en := en.New() //英文翻译器
zh := zh.New() //中文翻译器
// 第一个参数是必填,如果没有其他的语言设置,就用这第一个
// 后面的参数是支持多语言环境(
// uni := ut.New(en, en) 也是可以的
// uni := ut.New(en, zh, tw)
uni := ut.New(en, zh)
var ok bool
trans, ok := uni.GetTranslator("zh") //获取需要的语言
if !ok {
panic("form validation translator not found")
}
return trans
}
func NewValidate() *validator.Validate {
v := validator.New()
v.RegisterTagNameFunc(func(field reflect.StructField) string {
label := field.Tag.Get("label")
if label == "" {
return field.Name
}
return label
})
return v
}
func ValidateStruct(v interface{}) FieldsError {
if err := validate.Struct(v); err != nil {
validationErrs, ok := err.(validator.ValidationErrors)
if ok {
var fieldsErr FieldsError
for _, ve := range validationErrs {
fieldsErr = append(fieldsErr, NewFieldError(ve, translator))
}
return fieldsErr
}
}
return nil
}
func NewFieldError(err validator.FieldError, unt ut.Translator) *FieldError {
return &FieldError{
Field: err.StructField(),
Error: err.Translate(unt),
Raw: err,
Value: fmt.Sprintf("%v", err.Value()),
}
}