github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zvalid/bind.go (about) 1 package zvalid 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "strconv" 8 "strings" 9 10 "github.com/sohaha/zlsgo/zreflect" 11 ) 12 13 // ValidEle ValidEle 14 type ValidEle struct { 15 target interface{} 16 source Engine 17 } 18 19 // Silent an error occurred during filtering, no error is returned 20 func (v Engine) Silent() Engine { 21 v.silent = true 22 return v 23 } 24 25 // Default if a filtering error occurs, the default value is assigned to the variable 26 func (v Engine) Default(value interface{}) Engine { 27 return pushQueue(&v, func(v *Engine) *Engine { 28 if v.value == "" { 29 v.err = setError(v, "未设置验证值") 30 } 31 v.defaultValue = value 32 return v 33 }, true) 34 } 35 36 // Separator specify the separator of the slice type 37 func (v Engine) Separator(sep string) Engine { 38 if v.err != nil || v.value == "" { 39 return v 40 } 41 v.sep = sep 42 return v 43 } 44 45 // BatchError multiple error 46 func BatchError(rules ...Engine) error { 47 for i := range rules { 48 err := rules[i].Error() 49 if err != nil { 50 return err 51 } 52 } 53 return nil 54 } 55 56 // Batch assign multiple filtered results to the specified object 57 func Batch(elements ...*ValidEle) error { 58 for k := range elements { 59 e := elements[k] 60 if e == nil { 61 return nil 62 } 63 err := Var(e.target, e.source) 64 if err != nil { 65 return err 66 } 67 } 68 return nil 69 } 70 71 // BatchVar assign the filtered result to the specified variable 72 func BatchVar(target interface{}, source Engine) *ValidEle { 73 return &ValidEle{ 74 target: target, 75 source: source, 76 } 77 } 78 79 // Var assign the filtered result to the specified variable 80 func Var(target interface{}, source Engine, name ...string) error { 81 source = *source.valid() 82 if len(name) > 0 { 83 source.name = name[0] 84 } 85 if source.err != nil && source.defaultValue == nil { 86 if source.silent { 87 return nil 88 } 89 return source.err 90 } 91 var ( 92 val reflect.Value 93 k reflect.Kind 94 ) 95 val, ok := target.(reflect.Value) 96 if !ok { 97 val = zreflect.ValueOf(target) 98 if val.Kind() != reflect.Ptr { 99 if source.silent { 100 return nil 101 } 102 return fmt.Errorf("parameter must pass in a pointer type: %s", source.name) 103 } 104 if !val.Elem().CanSet() { 105 if source.silent { 106 return nil 107 } 108 return fmt.Errorf("target value of the variable cannot be changed: %s", source.name) 109 } 110 val = val.Elem() 111 k = val.Type().Kind() 112 } else { 113 k = val.Type().Kind() 114 } 115 116 if source.err == nil && source.value != "" { 117 source.err = setRawValue(k, val, source.value, source.sep) 118 } 119 120 if source.err != nil && source.defaultValue != nil { 121 if err := setDefaultValue(k, val, source.defaultValue); err != nil { 122 if source.silent { 123 return nil 124 } 125 return err 126 } 127 return nil 128 } else if source.err != nil { 129 if source.silent { 130 return nil 131 } 132 return errors.New(source.name + source.err.Error()) 133 } 134 135 return nil 136 } 137 138 func setRawValue(k reflect.Kind, val reflect.Value, value string, sep string) error { 139 typeErr := errors.New("不能用" + k.String() + "类型赋值") 140 switch k { 141 case reflect.String: 142 val.SetString(value) 143 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 144 v, err := strconv.ParseInt(value, 10, 64) 145 if err != nil { 146 return errors.New("必须是整数") 147 } 148 if val.OverflowInt(v) { 149 return typeErr 150 } 151 val.SetInt(v) 152 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 153 v, err := strconv.ParseUint(value, 10, 64) 154 if err != nil { 155 return errors.New("必须是无符号整数") 156 } 157 if val.OverflowUint(v) { 158 return typeErr 159 } 160 val.SetUint(v) 161 case reflect.Float32, reflect.Float64: 162 v, err := strconv.ParseFloat(value, 64) 163 if err != nil { 164 return errors.New("必须是小数") 165 } 166 if val.OverflowFloat(v) { 167 return typeErr 168 } 169 val.SetFloat(v) 170 case reflect.Bool: 171 v, err := strconv.ParseBool(value) 172 if err != nil { 173 return errors.New("必须是布尔值") 174 } 175 val.SetBool(v) 176 case reflect.Slice: 177 sliceType := val.Type().String() 178 if sliceType == "[]string" { 179 if sep == "" { 180 return errors.New("过滤规则的分隔符参数(sep)未定义") 181 } 182 val.Set(zreflect.ValueOf(strings.Split(value, sep))) 183 } 184 default: 185 return typeErr 186 } 187 188 return nil 189 } 190 191 func setDefaultValue(targetTypeOf reflect.Kind, targetValueOf reflect.Value, value interface{}) error { 192 valueTypeOf := zreflect.ValueOf(value) 193 if valueTypeOf.Kind() != targetTypeOf { 194 return errors.New("值类型默认值类型不相同" + valueTypeOf.String() + "/" + targetTypeOf.String()) 195 } 196 targetValueOf.Set(valueTypeOf) 197 return nil 198 }