Description
Hello, I've been using go-cmp
for a bit now and I've found that the two most common cases for needing an Option
are:
AllowUnexported
/IgnoreUnexported
- which is already easy to use- A
FilterPath
for fields that have values set fromtime.Now()
(time.Time
, ortime.Duration
)
It wasn't immediately obvious to me how to create a correct FilterPath
filter function. After a quick scan of the godoc my first approach was something like this:
func(path gocmp.Path) bool {
return path.Last().String() == ".Elapsed"
}
This worked, but it seems to me like it could potentially match fields that I don't want it to match if I used it with a large nested structure where multiple types had an Elapsed
field.
Digging into the godoc further I noticed that a bunch of the types embedded PathStep
, which made me realize that a more correct way of using Path
would probably be to iterate over the steps, type assert to the expected type, and compare to Name()
or Key()
.
My next iteration (gotestyourself/gotest.tools#62) looks something like this:
func fieldPathWithTypes(pathspec string) func(gocmp.Path) bool {
return func(path gocmp.Path) bool {
spec := strings.Split(pathspec, ".")
index := 0
for _, step := range path {
fieldStep, ok := step.(gocmp.StructField)
if !ok {
continue
}
if index >= len(spec) || spec[index] != fieldStep.Name() {
return false
}
index++
}
return index == len(spec)
}
}
Which could be made a lot simpler if it's expected that PathStep.String()
is stable and wont change between minor versions:
func fieldPathSimple(pathspec string) func(gocmp.Path) bool {
return func(path gocmp.Path) bool {
return path.String() == pathspec
}
}
The same idea could be applied using GoString()
if that is considered stable. The idea behind both of these functions is that it's much easier for a reader to understand a dotted path string, than it is to read a long function with a bunch of type assertions.
Questions:
- What is the expected/"best practice" way of using
PathStep
? Is it similar tofieldPathWithTypes
? - Would you be interested in a PR that adds a convenience function for building the
PathFilter
filter function from a simple string? This could be something likefieldPathWithTypes
or it could be more verbose (to match against something likeGoString()
. I believe the only type that can't be easily translated from a string representation would beTransform
. - Would you be interested in a PR that adds one or more examples for using
FilterPath
(based on feedback from these other questions) ?