-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathformat.go
More file actions
63 lines (55 loc) · 2.37 KB
/
Copy pathformat.go
File metadata and controls
63 lines (55 loc) · 2.37 KB
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
package jsonschema
// evaluateFormat checks if the data conforms to the format specified in the schema.
// According to the JSON Schema Draft 2020-12:
// - The "format" keyword defines the data format expected for a value.
// - The format must be a string that names a specific format which the value should conform to.
// - The function uses custom formats first, then falls back to the global `Formats` map.
// - If the format is not supported or not found, it may fall back to a no-op validation depending on configuration.
//
// This method ensures that data matches the expected format as specified in the schema.
// It handles formats as annotations by default, but can assert format validation if configured.
//
// Reference: https://json-schema.org/draft/2020-12/json-schema-validation#name-format
func evaluateFormat(schema *Schema, value any) *EvaluationError {
if schema.Format == nil {
return nil
}
formatName := *schema.Format
var formatDef *FormatDef
var customValidator func(any) bool
// Get the effective compiler (may be from parent or defaultCompiler)
compiler := schema.Compiler()
// 1. Check compiler-specific custom formats first
if compiler != nil {
compiler.customFormatsRW.RLock()
formatDef = compiler.customFormats[formatName]
compiler.customFormatsRW.RUnlock()
}
if formatDef != nil {
// Found in custom formats
if formatDef.Type != "" {
valueType := getDataType(value)
if valueType != formatDef.Type && (formatDef.Type != "number" || valueType != "integer") {
return nil // Type doesn't match, so skip validation
}
}
customValidator = formatDef.Validate
} else if globalValidator, ok := Formats[formatName]; ok {
// Fallback to global formats
customValidator = globalValidator
}
// If a validator was found (either custom or global)
if customValidator != nil {
if !customValidator(value) {
if compiler != nil && compiler.AssertFormat {
return NewEvaluationError("format", "format_mismatch", "Value does not match format '{format}'", map[string]any{"format": formatName})
}
}
return nil // Validation passed or not asserted
}
// If no validator was found and AssertFormat is true, fail
if compiler != nil && compiler.AssertFormat {
return NewEvaluationError("format", "unknown_format", "Unknown format '{format}'", map[string]any{"format": formatName})
}
return nil // Default behavior: ignore unknown formats
}