Files
openai/jsonschema/validate.go
T
zeekayandHanzo Dev 2e39f0248d Go 1.27.1, and the code it can say more simply
Modules declare go 1.27.1 and the build images follow. go fix applied the
modernizers, and the stream request helper is now a generic method on
Client; omitzero is not applied, since it changes what the JSON says.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 19:23:22 -07:00

86 lines
1.7 KiB
Go

package jsonschema
import (
"encoding/json"
"errors"
"slices"
)
func VerifySchemaAndUnmarshal(schema Definition, content []byte, v any) error {
var data any
err := json.Unmarshal(content, &data)
if err != nil {
return err
}
if !Validate(schema, data) {
return errors.New("data validation failed against the provided schema")
}
return json.Unmarshal(content, &v)
}
func Validate(schema Definition, data any) bool {
switch schema.Type {
case Object:
return validateObject(schema, data)
case Array:
return validateArray(schema, data)
case String:
_, ok := data.(string)
return ok
case Number: // float64 and int
_, ok := data.(float64)
if !ok {
_, ok = data.(int)
}
return ok
case Boolean:
_, ok := data.(bool)
return ok
case Integer:
// Golang unmarshals all numbers as float64, so we need to check if the float64 is an integer
if num, ok := data.(float64); ok {
return num == float64(int64(num))
}
_, ok := data.(int)
return ok
case Null:
return data == nil
default:
return false
}
}
func validateObject(schema Definition, data any) bool {
dataMap, ok := data.(map[string]any)
if !ok {
return false
}
for _, field := range schema.Required {
if _, exists := dataMap[field]; !exists {
return false
}
}
for key, valueSchema := range schema.Properties {
value, exists := dataMap[key]
if exists && !Validate(valueSchema, value) {
return false
} else if !exists && slices.Contains(schema.Required, key) {
return false
}
}
return true
}
func validateArray(schema Definition, data any) bool {
dataArray, ok := data.([]any)
if !ok {
return false
}
for _, item := range dataArray {
if !Validate(*schema.Items, item) {
return false
}
}
return true
}