39 lines
1000 B
Go
39 lines
1000 B
Go
// Package cmputil provides helper utilities for the go-cmp package.
|
|
package cmputil
|
|
|
|
import (
|
|
"reflect"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
func IgnoreProtobufUnexported() cmp.Option {
|
|
return cmp.FilterPath(filterProtobufUnexported, cmp.Ignore())
|
|
}
|
|
|
|
func filterProtobufUnexported(p cmp.Path) bool {
|
|
// Determine if the path is pointing to a struct field.
|
|
sf, ok := p.Index(-1).(cmp.StructField)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
// Return true if it is a proto.Message and the field is unexported.
|
|
return implementsProtoMessage(p.Index(-2).Type()) && !isExported(sf.Name())
|
|
}
|
|
|
|
// isExported reports whether the identifier is exported.
|
|
func isExported(id string) bool {
|
|
r, _ := utf8.DecodeRuneInString(id)
|
|
return unicode.IsUpper(r)
|
|
}
|
|
|
|
var messageType = reflect.TypeOf((*proto.Message)(nil)).Elem()
|
|
|
|
func implementsProtoMessage(t reflect.Type) bool {
|
|
return t.Implements(messageType) || reflect.PointerTo(t).Implements(messageType)
|
|
}
|