Source File
options.go
Belonging Package
github.com/google/go-cmp/cmp
package cmp
import (
)
type applicableOption interface {
Option
type coreOption interface {
Option
isCore()
}
type core struct{}
func (core) () {}
type Options []Option
func ( Options) ( *state, reflect.Type, , reflect.Value) ( applicableOption) {
for , := range {
switch := .filter(, , , ); .(type) {
case ignore:
return ignore{} // Only ignore can short-circuit evaluation
case validator:
= validator{} // Takes precedence over comparer or transformer
case *comparer, *transformer, Options:
switch .(type) {
case nil:
=
case *comparer, *transformer, Options:
= Options{, } // Conflicting comparers or transformers
}
}
}
return
}
func ( Options) ( *state, , reflect.Value) {
const = "ambiguous set of applicable options"
const = "consider using filters to ensure at most one Comparer or Transformer may apply"
var []string
for , := range flattenOptions(nil, ) {
= append(, fmt.Sprint())
}
:= strings.Join(, "\n\t")
panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", , .curPath, , ))
}
func ( Options) () string {
var []string
for , := range {
= append(, fmt.Sprint())
}
return fmt.Sprintf("Options{%s}", strings.Join(, ", "))
}
func ( func(Path) bool, Option) Option {
if == nil {
panic("invalid path filter function")
}
if := normalizeOption(); != nil {
return &pathFilter{fnc: , opt: }
}
return nil
}
type pathFilter struct {
core
fnc func(Path) bool
opt Option
}
func ( pathFilter) ( *state, reflect.Type, , reflect.Value) applicableOption {
if .fnc(.curPath) {
return .opt.filter(, , , )
}
return nil
}
func ( pathFilter) () string {
return fmt.Sprintf("FilterPath(%s, %v)", function.NameOf(reflect.ValueOf(.fnc)), .opt)
}
func ( interface{}, Option) Option {
:= reflect.ValueOf()
if !function.IsType(.Type(), function.ValueFilter) || .IsNil() {
panic(fmt.Sprintf("invalid values filter function: %T", ))
}
if := normalizeOption(); != nil {
:= &valuesFilter{fnc: , opt: }
if := .Type().In(0); .Kind() != reflect.Interface || .NumMethod() > 0 {
.typ =
}
return
}
return nil
}
type valuesFilter struct {
core
typ reflect.Type // T
fnc reflect.Value // func(T, T) bool
opt Option
}
func ( valuesFilter) ( *state, reflect.Type, , reflect.Value) applicableOption {
if !.IsValid() || !.CanInterface() || !.IsValid() || !.CanInterface() {
return nil
}
if (.typ == nil || .AssignableTo(.typ)) && .callTTBFunc(.fnc, , ) {
return .opt.filter(, , , )
}
return nil
}
func ( valuesFilter) () string {
return fmt.Sprintf("FilterValues(%s, %v)", function.NameOf(.fnc), .opt)
}
func () Option { return ignore{} }
type ignore struct{ core }
func (ignore) () bool { return false }
func (ignore) ( *state, reflect.Type, , reflect.Value) applicableOption { return ignore{} }
func (ignore) ( *state, , reflect.Value) { .report(true, reportByIgnore) }
func (ignore) () string { return "Ignore()" }
if !.CanInterface() || !.CanInterface() {
:= "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported"
var string
func ( string, interface{}) Option {
:= reflect.ValueOf()
if !function.IsType(.Type(), function.Transformer) || .IsNil() {
panic(fmt.Sprintf("invalid transformer function: %T", ))
}
if == "" {
= function.NameOf()
if !identsRx.MatchString() {
= "λ" // Lambda-symbol as placeholder name
}
} else if !identsRx.MatchString() {
panic(fmt.Sprintf("invalid name: %q", ))
}
:= &transformer{name: , fnc: reflect.ValueOf()}
if := .Type().In(0); .Kind() != reflect.Interface || .NumMethod() > 0 {
.typ =
}
return
}
type transformer struct {
core
name string
typ reflect.Type // T
fnc reflect.Value // func(T) R
}
func ( *transformer) () bool { return .typ != nil }
func ( *transformer) ( *state, reflect.Type, , reflect.Value) applicableOption {
for := len(.curPath) - 1; >= 0; -- {
if , := .curPath[].(Transform); ! {
break // Hit most recent non-Transform step
} else if == .trans {
return nil // Cannot directly use same Transform
}
}
if .typ == nil || .AssignableTo(.typ) {
return
}
return nil
}
func ( *transformer) ( *state, , reflect.Value) {
:= Transform{&transform{pathStep{typ: .fnc.Type().Out(0)}, }}
:= .callTRFunc(.fnc, , )
:= .callTRFunc(.fnc, , )
.vx, .vy = ,
.compareAny()
}
func ( transformer) () string {
return fmt.Sprintf("Transformer(%s, %s)", .name, function.NameOf(.fnc))
}
func ( interface{}) Option {
:= reflect.ValueOf()
if !function.IsType(.Type(), function.Equal) || .IsNil() {
panic(fmt.Sprintf("invalid comparer function: %T", ))
}
:= &comparer{fnc: }
if := .Type().In(0); .Kind() != reflect.Interface || .NumMethod() > 0 {
.typ =
}
return
}
type comparer struct {
core
typ reflect.Type // T
fnc reflect.Value // func(T, T) bool
}
func ( *comparer) () bool { return .typ != nil }
func ( *comparer) ( *state, reflect.Type, , reflect.Value) applicableOption {
if .typ == nil || .AssignableTo(.typ) {
return
}
return nil
}
func ( *comparer) ( *state, , reflect.Value) {
:= .callTTBFunc(.fnc, , )
.report(, reportByFunc)
}
func ( comparer) () string {
return fmt.Sprintf("Comparer(%s)", function.NameOf(.fnc))
}
type Result struct {
_ [0]func() // Make Result incomparable
flags resultFlags
}
func ( Result) () bool {
return .flags&(reportEqual|reportByIgnore) != 0
}
func ( Result) () bool {
return .flags&reportByIgnore != 0
}
func ( Result) () bool {
return .flags&reportByMethod != 0
}
func ( Result) () bool {
return .flags&reportByFunc != 0
}
func ( Result) () bool {
return .flags&reportByCycle != 0
}
type resultFlags uint
const (
_ resultFlags = (1 << iota) / 2
reportEqual
reportUnequal
reportByIgnore
reportByMethod
reportByFunc
reportByCycle
)
(PathStep)
(Result)
()
}) Option {
return reporter{}
}
type reporter struct{ reporterIface }
type reporterIface interface {
PushStep(PathStep)
Report(Result)
PopStep()
}
func (reporter) ( *state, reflect.Type, , reflect.Value) applicableOption {
panic("not implemented")
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |