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  }