github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/validator/validator__int.go (about) 1 package validator 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 "strconv" 8 9 "github.com/machinefi/w3bstream/pkg/depends/kit/validator/errors" 10 "github.com/machinefi/w3bstream/pkg/depends/kit/validator/rules" 11 "github.com/machinefi/w3bstream/pkg/depends/x/ptrx" 12 "github.com/machinefi/w3bstream/pkg/depends/x/typesx" 13 ) 14 15 type Int struct { 16 BitSize uint 17 18 Minimum *int64 19 Maximum *int64 20 MultipleOf int64 21 ExclusiveMaximum bool 22 ExclusiveMinimum bool 23 24 Enums map[int64]string 25 } 26 27 func init() { DefaultFactory.Register(&Int{}) } 28 29 func (Int) Names() []string { 30 return []string{"int", "int8", "int16", "int32", "int64"} 31 } 32 33 func (vi *Int) SetDefault() { 34 if vi != nil { 35 if vi.BitSize == 0 { 36 vi.BitSize = 32 37 } 38 if vi.Maximum == nil { 39 vi.Maximum = ptrx.Int64(MaxInt(vi.BitSize)) 40 } 41 if vi.Minimum == nil { 42 vi.Minimum = ptrx.Int64(MinInt(vi.BitSize)) 43 } 44 } 45 } 46 47 var ( 48 TargetIntValue = "int value" 49 ) 50 51 func (vi *Int) Validate(v interface{}) error { 52 rv, ok := v.(reflect.Value) 53 if !ok { 54 rv = reflect.ValueOf(v) 55 } 56 57 if k := rv.Type().Kind(); !typesx.IsSignedIntReflectKind(k) { 58 return errors.NewUnsupportedTypeError(rv.Type().String(), vi.String()) 59 } 60 61 val := rv.Int() 62 63 if vi.Enums != nil { 64 if _, ok := vi.Enums[val]; !ok { 65 values := make([]interface{}, 0) 66 for _, v := range vi.Enums { 67 values = append(values, v) 68 } 69 70 return &errors.NotInEnumError{ 71 Target: TargetIntValue, 72 Current: val, 73 Enums: values, 74 } 75 } 76 return nil 77 } 78 79 minimum := *vi.Minimum 80 maximum := *vi.Maximum 81 82 if ((vi.ExclusiveMinimum && val == minimum) || val < minimum) || 83 ((vi.ExclusiveMaximum && val == maximum) || val > maximum) { 84 return &errors.OutOfRangeError{ 85 Target: TargetFloatValue, 86 Current: val, 87 Minimum: minimum, 88 ExclusiveMinimum: vi.ExclusiveMinimum, 89 Maximum: maximum, 90 ExclusiveMaximum: vi.ExclusiveMaximum, 91 } 92 } 93 94 if vi.MultipleOf != 0 { 95 if val%vi.MultipleOf != 0 { 96 return &errors.MultipleOfError{ 97 Target: TargetFloatValue, 98 Current: val, 99 MultipleOf: vi.MultipleOf, 100 } 101 } 102 } 103 104 return nil 105 } 106 107 func (Int) New(ctx context.Context, r *Rule) (Validator, error) { 108 vi := &Int{} 109 110 bits, err := IntRuleBitSize(r) 111 if err != nil { 112 return nil, err 113 } 114 vi.BitSize = uint(bits) 115 116 min, max, err := IntRuleRange(r, vi.BitSize) 117 if err != nil { 118 return nil, err 119 } 120 vi.Maximum, vi.Minimum = max, min 121 122 vi.SetDefault() 123 vi.ExclusiveMinimum = r.ExclusiveMin 124 vi.ExclusiveMaximum = r.ExclusiveMax 125 126 multiple, enums, err := IntRuleValues(r, int(vi.BitSize)) 127 if err != nil { 128 return nil, err 129 } 130 vi.MultipleOf, vi.Enums = multiple, enums 131 132 return vi, vi.TypeCheck(r) 133 } 134 135 func (vi *Int) TypeCheck(r *Rule) error { 136 switch r.Type.Kind() { 137 case reflect.Int8: 138 if vi.BitSize > 8 { 139 return fmt.Errorf("bit size too large for type %s", r.Type) 140 } 141 return nil 142 case reflect.Int16: 143 if vi.BitSize > 16 { 144 return fmt.Errorf("bit size too large for type %s", r.Type) 145 } 146 return nil 147 case reflect.Int, reflect.Int32: 148 if vi.BitSize > 32 { 149 return fmt.Errorf("bit size too large for type %s", r.Type) 150 } 151 return nil 152 case reflect.Int64: 153 return nil 154 } 155 return errors.NewUnsupportedTypeError(r.String(), vi.String()) 156 } 157 158 func (vi *Int) String() string { 159 r := rules.NewRule(vi.Names()[0]) 160 161 r.Params = []rules.Node{ 162 rules.NewLiteral([]byte(strconv.Itoa(int(vi.BitSize)))), 163 } 164 165 if vi.Minimum != nil || vi.Maximum != nil { 166 r.Range = make([]*rules.Lit, 2) 167 168 if vi.Minimum != nil { 169 r.Range[0] = rules.NewLiteral( 170 []byte(fmt.Sprintf("%d", *vi.Minimum)), 171 ) 172 } 173 174 if vi.Maximum != nil { 175 r.Range[1] = rules.NewLiteral( 176 []byte(fmt.Sprintf("%d", *vi.Maximum)), 177 ) 178 } 179 180 r.ExclusiveMin = vi.ExclusiveMinimum 181 r.ExclusiveMax = vi.ExclusiveMaximum 182 } 183 184 r.ExclusiveMin = vi.ExclusiveMinimum 185 r.ExclusiveMax = vi.ExclusiveMaximum 186 187 if vi.MultipleOf != 0 { 188 r.ValueMatrix = [][]*rules.Lit{{ 189 rules.NewLiteral([]byte("%" + fmt.Sprintf("%d", vi.MultipleOf))), 190 }} 191 } else if vi.Enums != nil { 192 ruleValues := make([]*rules.Lit, 0) 193 for _, str := range vi.Enums { 194 ruleValues = append(ruleValues, rules.NewLiteral([]byte(str))) 195 } 196 r.ValueMatrix = [][]*rules.Lit{ruleValues} 197 } 198 199 return string(r.Bytes()) 200 }