-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathconditional.go
77 lines (65 loc) · 3.03 KB
/
conditional.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package jsonschema
// EvaluateConditional evaluates the data against conditional subschemas defined by 'if', 'then', and 'else'.
// According to the JSON Schema Draft 2020-12:
// - The "if" keyword specifies a subschema to conditionally validate data.
// - If data validates against the "if" subschema, "then" subschema must also validate the data if "then" is present.
// - If data does not validate against the "if" subschema, "else" subschema must validate the data if "else" is present.
// - This function ensures data conformity based on the provided conditional subschemaschema.
// - The function ignores "then" and "else" if "if" is not present.
//
// This function serves as a central feature for conditional logic application in JSON Schema validation.
//
// Reference: https://json-schema.org/draft/2020-12/json-schema-core#name-if
func evaluateConditional(schema *Schema, instance interface{}, evaluatedProps map[string]bool, evaluatedItems map[int]bool, dynamicScope *DynamicScope) ([]*EvaluationResult, *EvaluationError) {
if schema.If == nil {
// If there's no 'if' condition defined, nothing to validate conditionally.
return nil, nil
}
// Evaluate the 'if' condition
ifResult, ifEvaluatedProps, ifEvaluatedItems := schema.If.evaluate(instance, dynamicScope)
results := []*EvaluationResult{}
if ifResult != nil {
//nolint:errcheck
ifResult.SetEvaluationPath("/if").
SetSchemaLocation(schema.GetSchemaLocation("/if")).
SetInstanceLocation("")
results = append(results, ifResult)
if ifResult.IsValid() {
// Merge maps only if 'if' condition is successfully validated
mergeStringMaps(evaluatedProps, ifEvaluatedProps)
mergeIntMaps(evaluatedItems, ifEvaluatedItems)
if schema.Then != nil {
thenResult, thenEvaluatedProps, thenEvaluatedItems := schema.Then.evaluate(instance, dynamicScope)
if thenResult != nil {
//nolint:errcheck
thenResult.SetEvaluationPath("/then").
SetSchemaLocation(schema.GetSchemaLocation("/then")).
SetInstanceLocation("")
results = append(results, thenResult)
if !thenResult.IsValid() {
return results, NewEvaluationError("then", "if_then_mismatch",
"Value meets the 'if' condition but does not match the 'then' schema")
} else {
// Merge maps only if 'then' condition is successfully validated
mergeStringMaps(evaluatedProps, thenEvaluatedProps)
mergeIntMaps(evaluatedItems, thenEvaluatedItems)
}
}
}
} else if schema.Else != nil {
elseResult, elseEvaluatedProps, elseEvaluatedItems := schema.Else.evaluate(instance, dynamicScope)
if elseResult != nil {
results = append(results, elseResult)
if !elseResult.IsValid() {
return results, NewEvaluationError("else", "if_else_mismatch",
"Value fails the 'if' condition and does not match the 'else' schema")
} else {
// Merge maps only if 'else' condition is successfully validated
mergeStringMaps(evaluatedProps, elseEvaluatedProps)
mergeIntMaps(evaluatedItems, elseEvaluatedItems)
}
}
}
}
return results, nil
}