diff options
Diffstat (limited to 'common/hexutil/json.go')
-rw-r--r-- | common/hexutil/json.go | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/common/hexutil/json.go b/common/hexutil/json.go index 1bc1d014c..943288fad 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -18,15 +18,19 @@ package hexutil import ( "encoding/hex" - "errors" + "encoding/json" "fmt" "math/big" + "reflect" "strconv" ) var ( - textZero = []byte(`0x0`) - errNonString = errors.New("cannot unmarshal non-string as hex data") + textZero = []byte(`0x0`) + bytesT = reflect.TypeOf(Bytes(nil)) + bigT = reflect.TypeOf((*Big)(nil)) + uintT = reflect.TypeOf(Uint(0)) + uint64T = reflect.TypeOf(Uint64(0)) ) // Bytes marshals/unmarshals as a JSON string with 0x prefix. @@ -44,9 +48,9 @@ func (b Bytes) MarshalText() ([]byte, error) { // UnmarshalJSON implements json.Unmarshaler. func (b *Bytes) UnmarshalJSON(input []byte) error { if !isString(input) { - return errNonString + return errNonString(bytesT) } - return b.UnmarshalText(input[1 : len(input)-1]) + return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT) } // UnmarshalText implements encoding.TextUnmarshaler. @@ -69,6 +73,16 @@ func (b Bytes) String() string { return Encode(b) } +// UnmarshalFixedJSON decodes the input as a string with 0x prefix. The length of out +// determines the required input length. This function is commonly used to implement the +// UnmarshalJSON method for fixed-size types. +func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error { + if !isString(input) { + return errNonString(typ) + } + return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ) +} + // UnmarshalFixedText decodes the input as a string with 0x prefix. The length of out // determines the required input length. This function is commonly used to implement the // UnmarshalText method for fixed-size types. @@ -127,9 +141,9 @@ func (b Big) MarshalText() ([]byte, error) { // UnmarshalJSON implements json.Unmarshaler. func (b *Big) UnmarshalJSON(input []byte) error { if !isString(input) { - return errNonString + return errNonString(bigT) } - return b.UnmarshalText(input[1 : len(input)-1]) + return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bigT) } // UnmarshalText implements encoding.TextUnmarshaler @@ -189,9 +203,9 @@ func (b Uint64) MarshalText() ([]byte, error) { // UnmarshalJSON implements json.Unmarshaler. func (b *Uint64) UnmarshalJSON(input []byte) error { if !isString(input) { - return errNonString + return errNonString(uint64T) } - return b.UnmarshalText(input[1 : len(input)-1]) + return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uint64T) } // UnmarshalText implements encoding.TextUnmarshaler @@ -233,9 +247,9 @@ func (b Uint) MarshalText() ([]byte, error) { // UnmarshalJSON implements json.Unmarshaler. func (b *Uint) UnmarshalJSON(input []byte) error { if !isString(input) { - return errNonString + return errNonString(uintT) } - return b.UnmarshalText(input[1 : len(input)-1]) + return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uintT) } // UnmarshalText implements encoding.TextUnmarshaler. @@ -295,3 +309,14 @@ func checkNumberText(input []byte) (raw []byte, err error) { } return input, nil } + +func wrapTypeError(err error, typ reflect.Type) error { + if _, ok := err.(*decError); ok { + return &json.UnmarshalTypeError{Value: err.Error(), Type: typ} + } + return err +} + +func errNonString(typ reflect.Type) error { + return &json.UnmarshalTypeError{Value: "non-string", Type: typ} +} |