blockbook/bchain/coins/btc/codec.go

97 lines
2.2 KiB
Go

package btc
import (
"encoding/json"
"errors"
"reflect"
)
// RPCMarshaler is used for marshalling requests to Bitcoin Type RPC interfaces
type RPCMarshaler interface {
Marshal(v interface{}) ([]byte, error)
}
// JSONMarshalerV2 is used for marshalling requests to newer Bitcoin Type RPC interfaces
type JSONMarshalerV2 struct{}
// Marshal converts struct passed by parameter to JSON
func (JSONMarshalerV2) Marshal(v interface{}) ([]byte, error) {
d, err := json.Marshal(v)
if err != nil {
return nil, err
}
return d, nil
}
// ErrInvalidValue is error returned by JSONMarshalerV1.Marshal if the passed structure contains invalid value
var ErrInvalidValue = errors.New("Invalid value to marshal")
// JSONMarshalerV1 is used for marshalling requests to legacy Bitcoin Type RPC interfaces
type JSONMarshalerV1 struct{}
// Marshal converts struct passed by parameter to JSON
func (JSONMarshalerV1) Marshal(v interface{}) ([]byte, error) {
u := cmdUntypedParams{}
switch v := v.(type) {
case *CmdGetBlock:
var t bool
if v.Params.Verbosity > 0 {
t = true
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.BlockHash)
u.Params = append(u.Params, t)
case *CmdGetRawTransaction:
var n int
if v.Params.Verbose {
n = 1
}
u.Method = v.Method
u.Params = append(u.Params, v.Params.Txid)
u.Params = append(u.Params, n)
default:
{
v := reflect.ValueOf(v).Elem()
f := v.FieldByName("Method")
if !f.IsValid() || f.Kind() != reflect.String {
return nil, ErrInvalidValue
}
u.Method = f.String()
f = v.FieldByName("Params")
if f.IsValid() {
var arr []interface{}
switch f.Kind() {
case reflect.Slice:
arr = make([]interface{}, f.Len())
for i := 0; i < f.Len(); i++ {
arr[i] = f.Index(i).Interface()
}
case reflect.Struct:
arr = make([]interface{}, f.NumField())
for i := 0; i < f.NumField(); i++ {
arr[i] = f.Field(i).Interface()
}
default:
return nil, ErrInvalidValue
}
u.Params = arr
}
}
}
d, err := json.Marshal(u)
if err != nil {
return nil, err
}
return d, nil
}
type cmdUntypedParams struct {
Method string `json:"method"`
Params []interface{} `json:"params,omitempty"`
}