github.com/kaptinlin/jsonschema@v0.4.6/items.go (about) 1 package jsonschema 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 ) 8 9 // EvaluateItems checks if the data's array items conform to the subschema or boolean condition specified in the 'items' attribute of the schema. 10 // According to the JSON Schema Draft 2020-12: 11 // - The value of "items" MUST be either a valid JSON Schema or a boolean. 12 // - If "items" is a Schema, each element of the instance array must conform to this subschema. 13 // - If "items" is boolean and is true, any array elements are valid. 14 // - If "items" is boolean and is false, no array elements are valid unless the array is empty. 15 // 16 // This method ensures that array elements conform to the constraints defined in the items attribute. 17 // If any array element does not conform, it returns a EvaluationError detailing the issue. 18 // 19 // Reference: https://json-schema.org/draft/2020-12/json-schema-core#name-items 20 func evaluateItems(schema *Schema, array []interface{}, _ map[string]bool, evaluatedItems map[int]bool, dynamicScope *DynamicScope) ([]*EvaluationResult, *EvaluationError) { 21 if schema.Items == nil { 22 return nil, nil // // No 'items' constraints to validate against 23 } 24 25 invalid_indexs := []string{} 26 results := []*EvaluationResult{} 27 28 // Number of prefix items to skip before regular item validation 29 startIndex := len(schema.PrefixItems) 30 31 // Check if the general 'items' schema is available and proceed with validation if it's not explicitly false 32 if schema.Items != nil { 33 // Ensure that we only access indices within the range of existing array elements 34 for i := startIndex; i < len(array); i++ { 35 item := array[i] 36 result, _, _ := schema.Items.evaluate(item, dynamicScope) 37 if result != nil { 38 //nolint:errcheck 39 result.SetEvaluationPath(fmt.Sprintf("/items/%d", i)). 40 SetSchemaLocation(schema.GetSchemaLocation(fmt.Sprintf("/items/%d", i))). 41 SetInstanceLocation(fmt.Sprintf("/%d", i)) 42 43 if result.IsValid() { 44 evaluatedItems[i] = true // Mark the item as evaluated if it passes schema validation. 45 } else { 46 results = append(results, result) 47 invalid_indexs = append(invalid_indexs, strconv.Itoa(i)) 48 } 49 } 50 } 51 } 52 53 if len(invalid_indexs) == 1 { 54 return results, NewEvaluationError("items", "item_mismatch", "Item at index {index} does not match the schema", map[string]interface{}{ 55 "index": invalid_indexs[0], 56 }) 57 } else if len(invalid_indexs) > 1 { 58 return results, NewEvaluationError("items", "items_mismatch", "Items at index {indexs} do not match the schema", map[string]interface{}{ 59 "indexs": strings.Join(invalid_indexs, ", "), 60 }) 61 } 62 return results, nil 63 }