Files
tendermint/pkg/metadata/utils.go
2021-08-20 16:41:02 +02:00

76 lines
1.6 KiB
Go

package metadata
import (
"reflect"
gogotypes "github.com/gogo/protobuf/types"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
)
// Go lacks a simple and safe way to see if something is a typed nil.
// See:
// - https://dave.cheney.net/2017/08/09/typed-nils-in-go-2
// - https://groups.google.com/forum/#!topic/golang-nuts/wnH302gBa4I/discussion
// - https://github.com/golang/go/issues/21538
func isTypedNil(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice:
return rv.IsNil()
default:
return false
}
}
// Returns true if it has zero length.
func isEmpty(o interface{}) bool {
rv := reflect.ValueOf(o)
switch rv.Kind() {
case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
return rv.Len() == 0
default:
return false
}
}
// CdcEncode returns nil if the input is nil, otherwise returns
// proto.Marshal(<type>Value{Value: item})
func CdcEncode(item interface{}) []byte {
if item != nil && !isTypedNil(item) && !isEmpty(item) {
switch item := item.(type) {
case string:
i := gogotypes.StringValue{
Value: item,
}
bz, err := i.Marshal()
if err != nil {
return nil
}
return bz
case int64:
i := gogotypes.Int64Value{
Value: item,
}
bz, err := i.Marshal()
if err != nil {
return nil
}
return bz
case tmbytes.HexBytes:
i := gogotypes.BytesValue{
Value: item,
}
bz, err := i.Marshal()
if err != nil {
return nil
}
return bz
default:
return nil
}
}
return nil
}