github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/accounts/abi/error.go (about)

     1  package abi
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  )
     8  
     9  var (
    10  	errBadBool = errors.New("abi: improperly encoded boolean value")
    11  )
    12  
    13  func formatSliceString(kind reflect.Kind, sliceSize int) string {
    14  	if sliceSize == -1 {
    15  		return fmt.Sprintf("[]%v", kind)
    16  	}
    17  	return fmt.Sprintf("[%d]%v", sliceSize, kind)
    18  }
    19  
    20  func sliceTypeCheck(t Type, val reflect.Value) error {
    21  	if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
    22  		return typeErr(formatSliceString(t.Kind, t.Size), val.Type())
    23  	}
    24  
    25  	if t.T == ArrayTy && val.Len() != t.Size {
    26  		return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
    27  	}
    28  
    29  	if t.Elem.T == SliceTy {
    30  		if val.Len() > 0 {
    31  			return sliceTypeCheck(*t.Elem, val.Index(0))
    32  		}
    33  	} else if t.Elem.T == ArrayTy {
    34  		return sliceTypeCheck(*t.Elem, val.Index(0))
    35  	}
    36  
    37  	if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind {
    38  		return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type())
    39  	}
    40  	return nil
    41  }
    42  
    43  func typeCheck(t Type, value reflect.Value) error {
    44  	if t.T == SliceTy || t.T == ArrayTy {
    45  		return sliceTypeCheck(t, value)
    46  	}
    47  
    48  	if t.Kind != value.Kind() {
    49  		return typeErr(t.Kind, value.Kind())
    50  	} else if t.T == FixedBytesTy && t.Size != value.Len() {
    51  		return typeErr(t.Type, value.Type())
    52  	} else {
    53  		return nil
    54  	}
    55  
    56  }
    57  
    58  func typeErr(expected, got interface{}) error {
    59  	return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected)
    60  }