Move checkField to valueproof.go and rename checkPath to checkResolves

This commit is contained in:
2026-09-30 21:43:24 +02:00
committed by Lillem4n
parent cb7b43609f
commit 698ac036d5
7 changed files with 37 additions and 39 deletions
+1 -1
View File
@@ -902,7 +902,7 @@ checksum.go the check characters a derivation appends, and the IBAN they sit
transform.go the builtins that rewrite an operand's value, and the ASCII folding transform.go the builtins that rewrite an operand's value, and the ASCII folding
calc.go the {calc()} arithmetic evaluator: parser, eval, validation calc.go the {calc()} arithmetic evaluator: parser, eval, validation
datatype.go column datatypes: DataType, where datatype and null may sit, a column's datatype datatype.go column datatypes: DataType, where datatype and null may sit, a column's datatype
valueproof.go the value proof: what a typed column or calc operand holds, checked at load valueproof.go the value proof: what a typed column, calc operand or struct field holds, checked at load
data.go the load path: fs.FS folders/files -> merged namespace tree, and the bind pipeline every entry point runs data.go the load path: fs.FS folders/files -> merged namespace tree, and the bind pipeline every entry point runs
cmd/fejkdata/ the fejkdata CLI cmd/fejkdata/ the fejkdata CLI
data/ shipped data (JSON, and a TSV per table), embedded at build: locale folders, geo, misc data/ shipped data (JSON, and a TSV per table), embedded at build: locale folders, geo, misc
+1 -1
View File
@@ -262,7 +262,7 @@ func checkArm(name string, fields map[string]node, wholeToken bool) error {
} }
return fmt.Errorf("no field %q", a.head) return fmt.Errorf("no field %q", a.head)
} }
if err := checkPath(field, a.tail, a.head); err != nil { if err := checkResolves(field, a.tail, a.head); err != nil {
return fmt.Errorf("field %q: %w", a.head, err) return fmt.Errorf("field %q: %w", a.head, err)
} }
return nil return nil
+2 -2
View File
@@ -472,12 +472,12 @@ func unreachableInChoice(c *choice, want string) error {
return fmt.Errorf("not every variant of this %d-way choice carries %q; all carry %v", len(c.items), want, offered) return fmt.Errorf("not every variant of this %d-way choice carries %q; all carry %v", len(c.items), want, offered)
} }
func checkPath(n node, tail []string, level string) error { func checkResolves(n node, tail []string, level string) error {
_, err := (&pathCheck{level: level, tail: tail}).run(n) _, err := (&pathCheck{level: level, tail: tail}).run(n)
return err return err
} }
// compilePath compiles a path checkPath proved. // compilePath compiles a path checkResolves proved.
func compilePath(n node, tail []string) pathCheck { func compilePath(n node, tail []string) pathCheck {
w := pathCheck{tail: tail} w := pathCheck{tail: tail}
if _, err := w.run(n); err != nil { if _, err := w.run(n); err != nil {
+1 -1
View File
@@ -147,7 +147,7 @@ func (t *template) resolveLink(folder []string, path, category string, root map[
if category != "" && head == "/"+category { if category != "" && head == "/"+category {
return link, fmt.Errorf("%s: reference {%s}: names the category it sits in; read a sibling field as a path, or move the shared value into its own category and reference that", path, name) return link, fmt.Errorf("%s: reference {%s}: names the category it sits in; read a sibling field as a path, or move the shared value into its own category and reference that", path, name)
} }
if err := checkPath(target, tail, head); err != nil { if err := checkResolves(target, tail, head); err != nil {
return link, fmt.Errorf("%s: reference {%s}: %w", path, name, err) return link, fmt.Errorf("%s: reference {%s}: %w", path, name, err)
} }
link.refHeads[head] = target link.refHeads[head] = target
-31
View File
@@ -317,37 +317,6 @@ func (k columnKind) holds(v proven) bool {
return v.lo >= k.lo && v.hi <= k.hi return v.lo >= k.lo && v.hi <= k.hi
} }
// checkField rejects a column a field of Go type ft cannot fill: a datatype, which the Go type
// sets, a null outside a pointer, or a value its kind's datatype or range refuses.
func (p *valueProof) checkField(label string, ft reflect.Type, column node) error {
items, _ := columnItems(column)
for _, it := range items {
if it.datatype != DataTypeString {
return fmt.Errorf("%s: its Go type %s sets the datatype; drop \"datatype\"", label, ft)
}
}
elem := ft
if ft.Kind() == reflect.Pointer {
elem = ft.Elem()
} else if p.proveColumn(column).nullable {
return fmt.Errorf("%s: its tag can draw null, which %s cannot hold; make it *%s", label, ft, ft)
}
kind := columnKinds[elem.Kind()]
if kind.datatype == DataTypeString {
return nil
}
for _, it := range items {
v := p.proveColumnItem(it)
if reason := v.not[kind.datatype]; reason != "" {
return fmt.Errorf("%s (%s): %s", label, ft, reason)
}
if !kind.holds(v) {
return fmt.Errorf("%s (%s): %q is not proven within %s; narrow it to that range, or make the field %s", label, ft, it.format, elem.Kind(), kind.wider)
}
}
return nil
}
// fill draws the record into v's tagged fields, then each nested struct as a record of its own. // fill draws the record into v's tagged fields, then each nested struct as a record of its own.
func (s *structShape) fill(state *generatorState, v reflect.Value) { func (s *structShape) fill(state *generatorState, v reflect.Value) {
if s.record != nil { if s.record != nil {
-3
View File
@@ -40,9 +40,6 @@ maintainer chose on 2026-09-30 to go on with the path steps regardless.
This round, in order: This round, in order:
- Move `valueProof.checkField` to `valueproof.go`, and rename `checkPath`, which differs
from the `pathCheck` type it wraps by word order alone: both architects placed them
wrong.
- Correct the claims readers followed wrong: `IsTemplate`'s doc says an argument holding - Correct the claims readers followed wrong: `IsTemplate`'s doc says an argument holding
a bracket that is not valid JSON errors, where `misc.territory[SE]` is a path; the a bracket that is not valid JSON errors, where `misc.territory[SE]` is a path; the
README says rows are indexed on the first draw, where `New` builds the key map; and README says rows are indexed on the first draw, where `New` builds the key map; and
+32
View File
@@ -3,6 +3,7 @@ package fejkdata
import ( import (
"fmt" "fmt"
"math" "math"
"reflect"
"regexp" "regexp"
"slices" "slices"
"strconv" "strconv"
@@ -43,6 +44,37 @@ func (p *valueProof) checkDatatype(path string, n node) error {
return nil return nil
} }
// checkField rejects a column a field of Go type ft cannot fill: a datatype, which the Go type
// sets, a null outside a pointer, or a value its kind's datatype or range refuses.
func (p *valueProof) checkField(label string, ft reflect.Type, column node) error {
items, _ := columnItems(column)
for _, it := range items {
if it.datatype != DataTypeString {
return fmt.Errorf("%s: its Go type %s sets the datatype; drop \"datatype\"", label, ft)
}
}
elem := ft
if ft.Kind() == reflect.Pointer {
elem = ft.Elem()
} else if p.proveColumn(column).nullable {
return fmt.Errorf("%s: its tag can draw null, which %s cannot hold; make it *%s", label, ft, ft)
}
kind := columnKinds[elem.Kind()]
if kind.datatype == DataTypeString {
return nil
}
for _, it := range items {
v := p.proveColumnItem(it)
if reason := v.not[kind.datatype]; reason != "" {
return fmt.Errorf("%s (%s): %s", label, ft, reason)
}
if !kind.holds(v) {
return fmt.Errorf("%s (%s): %q is not proven within %s; narrow it to that range, or make the field %s", label, ft, it.format, elem.Kind(), kind.wider)
}
}
return nil
}
// proveColumnItem proves a column item: what it renders, or, when it is a column it reads, that column. // proveColumnItem proves a column item: what it renders, or, when it is a column it reads, that column.
func (p *valueProof) proveColumnItem(t *template) proven { func (p *valueProof) proveColumnItem(t *template) proven {
if t.link.readsColumn == nil { if t.link.readsColumn == nil {