in core.go [51:97]
func Strict(laxValidator validator.Validator) validator.Validator {
return func(actual interface{}) *llresult.Results {
res := laxValidator(actual)
// When validating nil objects the lax validator is by definition sufficient
if actual == nil {
return res
}
// The inner workings of this are a little weird
// We use a hash of dotted paths to track the res
// We can Check if a key had a test associated with it by looking up the laxValidator
// result data
// What's trickier is intermediate maps, maps don't usually have explicit tests, they usually just have
// their properties tested.
// This method counts an intermediate map as tested if a subkey is tested.
// Since the datastructure we have to search is a flattened hashmap of the original map we take that hashmap
// and turn it into a sorted string array, then do a binary prefix search to determine if a subkey was tested.
// It's a little weird, but is fairly efficient. We could stop using the flattened map as a datastructure, but
// that would add complexity elsewhere. Probably a good refactor at some point, but not worth it now.
validatedPaths := []string{}
for k := range res.Fields {
validatedPaths = append(validatedPaths, k)
}
sort.Strings(validatedPaths)
walk(reflect.ValueOf(actual), false, func(woi walkObserverInfo) error {
_, validatedExactly := res.Fields[woi.path.String()]
if validatedExactly {
return nil // This key was tested, passes strict test
}
// Search returns the point just before an actual match (since we ruled out an exact match with the cheaper
// hash Check above. We have to validate the actual match with a prefix Check as well
matchIdx := sort.SearchStrings(validatedPaths, woi.path.String())
if matchIdx < len(validatedPaths) && strings.HasPrefix(validatedPaths[matchIdx], woi.path.String()) {
return nil
}
res.Merge(llresult.StrictFailureResult(woi.path))
return nil
})
return res
}
}