Files
orbit/weave/definition/data.go

76 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package definition
import (
"bytes"
"encoding/json"
"git.yuntuo.hk/k2safe/orbit/internal/jsonvalue"
)
// ValidateData 在实例输入、任务成功结果、信号和块输出边界复用同一类型契约。
// 使用精确JSON数值文本;大小、重复字段、Unicode和嵌套限制先于类型检查。
func ValidateData(schema Type, raw json.RawMessage) error {
if err := checkType(schema, 0); err != nil {
return err
}
if len(raw) == 0 || len(raw) > 256<<10 {
return invalid("data", "JSON value required, maximum 256 KiB")
}
if _, err := jsonvalue.Canonical(raw); err != nil {
return invalid("data", "invalid JSON, duplicate fields or unsupported value limits")
}
var value any
d := json.NewDecoder(bytes.NewReader(raw))
d.UseNumber()
if err := d.Decode(&value); err != nil {
return invalid("data", "invalid JSON value")
}
return matchData(schema, value)
}
func matchData(schema Type, value any) error {
valid := false
switch schema.Kind {
case "JSON":
return nil
case "NULL":
valid = value == nil
case "STRING":
v, ok := value.(string)
valid = ok && (len(schema.Enum) == 0 || contains(schema.Enum, v))
case "NUMBER":
_, valid = value.(json.Number)
case "BOOLEAN":
_, valid = value.(bool)
case "OBJECT":
v, ok := value.(map[string]any)
if !ok || len(v) != len(schema.Fields) {
return invalid("data", "object fields do not match declared type")
}
for key, t := range schema.Fields {
child, ok := v[key]
if !ok {
return invalid("data", "required object field missing")
}
if err := matchData(t, child); err != nil {
return err
}
}
return nil
case "ARRAY":
v, ok := value.([]any)
if !ok || len(v) > 4096 {
return invalid("data", "array required, maximum 4096 elements")
}
for _, child := range v {
if err := matchData(*schema.Items, child); err != nil {
return err
}
}
return nil
}
if !valid {
return invalid("data", "value does not match declared type")
}
return nil
}