func Strict()

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