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(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 }