github.com/kaptinlin/jsonschema@v0.4.6/anyOf.go (about) 1 package jsonschema 2 3 import ( 4 "fmt" 5 ) 6 7 // EvaluateAnyOf checks if the data conforms to at least one of the schemas specified in the anyOf attribute. 8 // According to the JSON Schema Draft 2020-12: 9 // - The "anyOf" keyword's value must be a non-empty array, where each item is either a valid JSON Schema or a boolean. 10 // - An instance validates successfully against this keyword if it validates successfully against at least one schema or is true for any boolean in this array. 11 // 12 // This function ensures that the data instance meets at least one of the specified constraints defined by the schemas or booleans in the anyOf array. 13 // If the instance fails to conform to all conditions in the array, it returns a EvaluationError detailing the specific failures. 14 // 15 // Reference: https://json-schema.org/draft/2020-12/json-schema-core#name-anyof 16 func evaluateAnyOf(schema *Schema, data interface{}, evaluatedProps map[string]bool, evaluatedItems map[int]bool, dynamicScope *DynamicScope) ([]*EvaluationResult, *EvaluationError) { 17 if len(schema.AnyOf) == 0 { 18 return nil, nil // No anyOf constraints to validate against. 19 } 20 21 var valid bool 22 results := []*EvaluationResult{} 23 24 for i, subSchema := range schema.AnyOf { 25 if subSchema != nil { 26 skipEval := false 27 if subSchema.Boolean != nil && *subSchema.Boolean { 28 // If the schema is `true`, skip updating evaluated properties and items. 29 skipEval = true 30 } 31 result, schemaEvaluatedProps, schemaEvaluatedItems := subSchema.evaluate(data, dynamicScope) 32 33 if result != nil { 34 results = append(results, result.SetEvaluationPath(fmt.Sprintf("/anyOf/%d", i)). 35 SetSchemaLocation(schema.GetSchemaLocation(fmt.Sprintf("/anyOf/%d", i))). 36 SetInstanceLocation(""), 37 ) 38 39 if result.IsValid() { 40 valid = true 41 // Merge maps only if the evaluation is successful 42 if !skipEval { 43 mergeStringMaps(evaluatedProps, schemaEvaluatedProps) 44 mergeIntMaps(evaluatedItems, schemaEvaluatedItems) 45 } 46 } 47 } 48 } 49 } 50 51 if valid { 52 return results, nil // Return nil only if at least one schema succeeds 53 } else { 54 return results, NewEvaluationError("anyOf", "any_of_item_mismatch", "Value does not match anyOf schema") 55 } 56 }