Support integer schema versions through typed decoding

This commit is contained in:
2026-09-12 00:25:54 +00:00
parent b3e7b62119
commit f5bbc2be5d
11 changed files with 484 additions and 38 deletions

View File

@@ -2,6 +2,7 @@ package configkit
import (
"reflect"
"strconv"
"gitea.maximumdirect.net/eric/ConfigKit/internal/document"
)
@@ -200,12 +201,18 @@ func checkVersion(rule *VersionRule, root *document.Node) []Diagnostic {
version.Null = true
case document.String:
version.Text = node.Text
case document.Number:
if isIntegerVersion(node) {
version.Text = node.Text
break
}
fallthrough
default:
location, _ := nearestDocumentLocation(root, rule.Path)
primary := documentLocationPointer(location)
return []Diagnostic{{
Code: CodeVersionType, Severity: SeverityError, Path: rule.Path.clone(),
Message: "schema version must be a string or null", Primary: primary,
Message: "schema version must be a string, integer, or null", Primary: primary,
}}
}
}
@@ -226,6 +233,33 @@ func checkVersion(rule *VersionRule, root *document.Node) []Diagnostic {
return canonicalDiagnostics(state.diagnostics)
}
func isIntegerVersion(node *document.Node) bool {
return node != nil && node.Kind == document.Number && integerPattern.MatchString(node.Text)
}
func pathMatches(configured *Path, current Path) bool {
if configured == nil || !configured.valid() || !current.valid() || len(configured.segments) != len(current.segments) {
return false
}
for i, expected := range configured.segments {
actual := current.segments[i]
if expected.kind == pathSegmentParsed {
if actual.kind == pathSegmentIndex {
if expected.key != strconv.Itoa(actual.index) {
return false
}
} else if expected.key != actual.key {
return false
}
continue
}
if expected.kind != actual.kind || expected.key != actual.key || expected.index != actual.index {
return false
}
}
return true
}
func documentLocationPointer(location document.Location) *Location {
if !locationKnown(location) {
return nil