v0.5.0 Unmapped reads any parsed value, UnknownKeys refuses what it names, decode errors name the key path
Test / test (push) Canceled after 0s

* Unmapped reads any parsed value; decode errors name the key path

Unmapped(data, v) names the keys of a value Parse produced that no field
of v's type takes, a table inside a document included, so a caller holding
a tree (after macro expansion, say) can refuse them as a Document's caller
does; Document.Unmapped calls it.

A decode error names where it failed by the key path the document spells,
rooms[1].width or by_key."a b".width, rather than by Go type and field
names and "index n" / "map key" segments; a key that cannot be bare, or
runs past 32 bytes, is quoted and cut as parse errors quote one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rsnp29663hDvPHPua37MhN

* UnknownKeys, the error naming the keys a caller refuses

A caller that refuses what Unmapped names returns UnknownKeys(keys),
"unknown key \"a\"" or "unknown keys \"a\", \"b.c\"", so every refusal
words them alike. vif's settings already format their own; its FSM
dialect would be the second copy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rsnp29663hDvPHPua37MhN

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
LixenandClaude Opus 5.5 authored and GitHub committed 2026-10-26 03:30:55 -04:00
1 parent 170e71f10a
commit 5c0a1c757a
5 files changed
+80 -16

No files matched your search

+24 -5
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"reflect"
"slices"
"strconv"
"strings"
)
@@ -253,12 +254,30 @@ func (d *Document) Tree() map[string]any { return d.tree }
func (d *Document) Decode(v any) error { return Decode(d.tree, v) }
// Unmapped names the keys of the document that no field of v's type takes, as
// Decode, which ignores them, would match them; each once and sorted. A key under
// a map or interface destination is taken, and one under an array of tables is
// named without its index.
func (d *Document) Unmapped(v any) []Key {
// the function Unmapped does
func (d *Document) Unmapped(v any) []Key { return Unmapped(d.tree, v) }
// UnknownKeys is the error of a caller that refuses the keys Unmapped names
type UnknownKeys []Key
func (u UnknownKeys) Error() string {
q := make([]string, len(u))
for i, k := range u {
q[i] = strconv.Quote(k.String())
}
if len(q) == 1 {
return "unknown key " + q[0]
}
return "unknown keys " + strings.Join(q, ", ")
}
// Unmapped names the keys of data, a value Parse produced, that no field of v's
// type takes, as Decode, which ignores them, would match them; each once and
// sorted. A key under a map or interface destination is taken, and one under an
// array of tables is named without its index.
func Unmapped(data any, v any) []Key {
seen := make(map[string]Key)
unmapped(d.tree, reflect.TypeOf(v), nil, seen, 0)
unmapped(data, reflect.TypeOf(v), nil, seen, 0)
out := make([]Key, 0, len(seen))
for _, k := range seen {
out = append(out, k)