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