github.com/kaptinlin/jsonschema@v0.4.6/prefixItems.go (about) 1 package jsonschema 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 ) 8 9 // EvaluatePrefixItems checks if each element in an array instance matches the schema specified at the same index in the 'prefixItems' array. 10 // According to the JSON Schema Draft 2020-12: 11 // - The value of "prefixItems" MUST be a non-empty array of valid JSON Schemas. 12 // - Validation succeeds if each element of the instance validates against the schema at the same position, if any. 13 // - This keyword does not constrain the length of the array; it validates only the prefix of the array up to the length of 'prefixItems'. 14 // - Produces an annotation value of the largest index validated if all items up to that index are valid. The value may be true if all items are valid. 15 // - Omitting this keyword implies an empty array behavior, meaning no validation is enforced on the array items. 16 // 17 // If validation fails, it returns a EvaluationError detailing the index and discrepancy. 18 func evaluatePrefixItems(schema *Schema, array []interface{}, _ map[string]bool, evaluatedItems map[int]bool, dynamicScope *DynamicScope) ([]*EvaluationResult, *EvaluationError) { 19 if len(schema.PrefixItems) == 0 { 20 return nil, nil // If no prefixItems are defined, there is nothing to validate against. 21 } 22 23 invalid_indexs := []string{} 24 results := []*EvaluationResult{} 25 26 for i, itemSchema := range schema.PrefixItems { 27 if i >= len(array) { 28 break // Stop validation if there are more schemas than array items. 29 } 30 31 result, _, _ := itemSchema.evaluate(array[i], dynamicScope) 32 if result != nil { 33 results = append(results, result.SetEvaluationPath(fmt.Sprintf("/prefixItems/%d", i)). 34 SetSchemaLocation(schema.GetSchemaLocation(fmt.Sprintf("/prefixItems/%d", i))). 35 SetInstanceLocation(fmt.Sprintf("/%d", i)), 36 ) 37 38 if result.IsValid() { 39 evaluatedItems[i] = true // Mark the item as evaluated if it passes schema validation. 40 } else { 41 invalid_indexs = append(invalid_indexs, strconv.Itoa(i)) 42 } 43 } 44 } 45 46 if len(invalid_indexs) == 1 { 47 return results, NewEvaluationError("prefixItems", "prefix_item_mismatch", "Item at index {index} does not match the prefixItems schema", map[string]interface{}{ 48 "index": invalid_indexs[0], 49 }) 50 } else if len(invalid_indexs) > 1 { 51 return results, NewEvaluationError("prefixItems", "prefix_items_mismatch", "Items at index {indexs} do not match the prefixItems schemas", map[string]interface{}{ 52 "indexs": strings.Join(invalid_indexs, ", "), 53 }) 54 } 55 56 return results, nil 57 }