github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/validator/validator_helper_int.go (about) 1 package validator 2 3 import ( 4 "bytes" 5 "fmt" 6 "strconv" 7 "unicode" 8 9 "github.com/machinefi/w3bstream/pkg/depends/kit/validator/errors" 10 ) 11 12 func MinInt(bits uint) int64 { return -(1 << (bits - 1)) } 13 14 func MaxInt(bits uint) int64 { return 1<<(bits-1) - 1 } 15 16 func IntRuleRange(r *Rule, bits uint) (*int64, *int64, error) { 17 if r.Range == nil { 18 return nil, nil, nil 19 } 20 21 typ := fmt.Sprintf("int<%d>", bits) 22 23 parseInt := func(b []byte) (*int64, error) { 24 if len(b) == 0 { 25 return nil, nil 26 } 27 n, err := strconv.ParseInt(string(b), 10, int(bits)) 28 if err != nil { 29 return nil, fmt.Errorf("%s value is not correct: %s", typ, err) 30 } 31 return &n, nil 32 } 33 34 ranges := r.Range 35 switch len(ranges) { 36 case 2: 37 min, err := parseInt(ranges[0].Bytes()) 38 if err != nil { 39 return nil, nil, fmt.Errorf("min %s", err) 40 } 41 max, err := parseInt(ranges[1].Bytes()) 42 if err != nil { 43 return nil, nil, fmt.Errorf("max %s", err) 44 } 45 if min != nil && max != nil && *max < *min { 46 return nil, nil, fmt.Errorf( 47 "max %s value must be equal or large than min expect %d, current %d", 48 typ, min, max, 49 ) 50 } 51 52 return min, max, nil 53 case 1: 54 min, err := parseInt(ranges[0].Bytes()) 55 if err != nil { 56 return nil, nil, fmt.Errorf("min %s", err) 57 } 58 return min, min, nil 59 } 60 return nil, nil, nil 61 } 62 63 func IntRuleBitSize(r *Rule) (bits uint64, err error) { 64 buf := &bytes.Buffer{} 65 66 for _, char := range r.Name { 67 if unicode.IsDigit(char) { 68 buf.WriteRune(char) 69 } 70 } 71 72 if buf.Len() == 0 && r.Params != nil { 73 if len(r.Params) != 1 { 74 err = fmt.Errorf("int should only 1 parameter, but got %d", len(r.Params)) 75 return 76 } 77 buf.Write(r.Params[0].Bytes()) 78 } 79 80 if buf.Len() != 0 { 81 s := buf.String() 82 bits, err = strconv.ParseUint(s, 10, 8) 83 if err != nil || bits > 64 { 84 err = errors.NewSyntaxError("int parameter should be valid bit size, but got `%s`", s) 85 return 86 } 87 } 88 89 if bits == 0 { 90 bits = 32 91 } 92 return 93 } 94 95 func IntRuleValues(r *Rule, bits int) (multiple int64, enums map[int64]string, err error) { 96 values := r.ComputedValues() 97 if values == nil { 98 return 99 } 100 101 if len(values) == 1 { 102 raw := values[0].Bytes() 103 if raw[0] == '%' { 104 raw = raw[1:] 105 multiple, err = strconv.ParseInt(string(raw), 10, bits) 106 if err != nil { 107 err = errors.NewSyntaxError( 108 "multipleOf should be a valid int%d value, but got `%s`", 109 bits, raw, 110 ) 111 return 112 } 113 } 114 } 115 116 if multiple == 0 { 117 enums = map[int64]string{} 118 for _, v := range values { 119 s := string(v.Bytes()) 120 enumv, _err := strconv.ParseInt(s, 10, bits) 121 if _err != nil { 122 err = errors.NewSyntaxError( 123 "enum should be a valid int%d value, but got `%s`", bits, v, 124 ) 125 return 126 } 127 enums[enumv] = s 128 } 129 } 130 return 131 }