Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33

Open
lilleman wants to merge 966 commits from worktree-todo-relative-dates-exact-counts into main
7 changed files with 18 additions and 18 deletions
Showing only changes of commit d0886e4795 - Show all commits
+1 -1
View File
@@ -962,7 +962,7 @@ name.go names: {x as n} bindings, the scopes they live in, and the reads
namefence.go the load fences over names namefence.go the load fences over names
pick.go a render's named picks: the frames of the name scopes rendering, the memo a pick keeps, and the reads kept under it pick.go a render's named picks: the frames of the name scopes rendering, the memo a pick keeps, and the reads kept under it
env.go renderEnv: what a render reads names and rows through env.go renderEnv: what a render reads names and rows through
path.go the dotted-path walks, and proving a path resolves path.go the dotted-path walks, and proving a path reaches a node
render.go Fake, the recursive renderer (choices, format strings, expansions) and the reads its tokens make render.go Fake, the recursive renderer (choices, format strings, expansions) and the reads its tokens make
record.go records: Record, the JSON/CSV/SQL serializers, and their entry points record.go records: Record, the JSON/CSV/SQL serializers, and their entry points
struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype struct.go structs: FakeStruct, fake tags as one record's columns, and a field's Go type as its column's datatype
+2 -2
View File
@@ -66,8 +66,8 @@ func mergeChildren(dst, src map[string]node) {
} }
} }
// nodeSet is the set of nodes one validation pass covers: the categories one load // nodeSet is the set of nodes one validation pass covers: one load's categories, or a
// reads, or a single inline node. // single inline node.
type nodeSet func(fn func(label string, n node) error) error type nodeSet func(fn func(label string, n node) error) error
// categorySite is a loaded category and where it sits: the folder holding it, that // categorySite is a loaded category and where it sits: the folder holding it, that
+7 -7
View File
@@ -23,22 +23,22 @@ package fejkdata
// `Generator.Fake`, `FakeRecord`, `Template.Fake` and `RecordTemplate.Fake` // `Generator.Fake`, `FakeRecord`, `Template.Fake` and `RecordTemplate.Fake`
// start one each, and `FakeStruct` one per record. // start one each, and `FakeStruct` one per record.
// - env — what a render reads names and rows through: `renderEnv`. // - env — what a render reads names and rows through: `renderEnv`.
// - scope — where a name is bound: a category, or one repeat iteration: `nameScope`.
// - named pick — the draw a token such as {/person as p} binds to a name, drawn // - named pick — the draw a token such as {/person as p} binds to a name, drawn
// on its first read and kept while its scope renders: `nameBinding`, // on its first read and kept while its scope renders: `nameBinding`,
// `namedPick`, `pickFrame`. // `namedPick`, `pickFrame`.
// - scope — where a name is bound: a category, or one repeat iteration: `nameScope`.
// - memo — what a named pick keeps its draws in, the variant drawn at each level // - memo — what a named pick keeps its draws in, the variant drawn at each level
// and the value each path read: `drawMemo`. // and the value each path read: `drawMemo`.
// - pin — fixing which row of a table one path, or one named pick, uses: // - pin — fixing which row of a table one path, or one named pick, uses:
// `pinSet`, `namedPick.pins`, `table.drawStep`. // `pinSet`, `namedPick.pins`, `table.drawStep`.
// - family — a table and every table reaching it through a chain of parent
// links.
// - link — a table's tie to its parent table, each row to its parent row: // - link — a table's tie to its parent table, each row to its parent row:
// `table.linkParent`. // `table.linkParent`.
// - resolve — tying each template's references and names to the assembled tree: // - family — a table and every table reaching it through a chain of parent
// `resolveTemplates`. // links.
// - head — the string a read starts from: a field's name, or a reference's // - resolve — tying a reference or a name to what it names in the assembled tree:
// category path with its sigil, /sv_SE.address: `arm.head`. The node it names is // `resolveTemplates`, `resolveRefs`.
// - head — the string a read starts from: a field or a name as written, or a
// reference's category path with its sigil, /sv_SE.address: `arm.head`. The node it names is
// the read's start: `template.startOf`, `nameTarget.start`. // the read's start: `template.startOf`, `nameTarget.start`.
// - fence — a load-time check, run over each category, template or struct as it // - fence — a load-time check, run over each category, template or struct as it
// loads or compiles, so rendering a compiled tree cannot fail. // loads or compiles, so rendering a compiled tree cannot fail.
+2 -2
View File
@@ -159,7 +159,7 @@ func checkArm(name string, fields map[string]node, wholeToken bool) (missing boo
} }
return true, fmt.Errorf("no field %q", a.head) return true, fmt.Errorf("no field %q", a.head)
} }
if err := checkPathResolves(field, a.tail, a.head); err != nil { if err := checkPathReaches(field, a.tail, a.head); err != nil {
return false, fmt.Errorf("field %q: %w", a.head, err) return false, fmt.Errorf("field %q: %w", a.head, err)
} }
return false, nil return false, nil
@@ -341,7 +341,7 @@ func (t *template) compileArm(name string, targets map[*nameBinding]nameTarget)
} }
target := targets[b] target := targets[b]
full := append(target.tail[:len(target.tail):len(target.tail)], a.tail...) full := append(target.tail[:len(target.tail):len(target.tail)], a.tail...)
if err := checkPathResolves(target.start, full, a.head); err != nil { if err := checkPathReaches(target.start, full, a.head); err != nil {
return a, err return a, err
} }
w := compilePath(target.start, full) w := compilePath(target.start, full)
+4 -4
View File
@@ -111,7 +111,7 @@ const (
stepParent // up to the table's parent, at the row its own row links to stepParent // up to the table's parent, at the row its own row links to
) )
// pathCheck proves a path resolves whichever way the draws go: every variant of a // pathCheck proves a path reaches a node whichever way the draws go: every variant of a
// choice carries the rest of it, and is walked, a selector names a row inside the // choice carries the rest of it, and is walked, a selector names a row inside the
// rows selected before it, and no level read carries a repeat. It compiles the steps // rows selected before it, and no level read carries a repeat. It compiles the steps
// a draw takes, and every leaf the path may render; level names the head in its errors. // a draw takes, and every leaf the path may render; level names the head in its errors.
@@ -237,7 +237,7 @@ func (w *pathCheck) walkEvery(c *choice, tail []string) (node, error) {
return last, nil return last, nil
} }
// probePath proves a path resolves without drawing, appending to steps the steps a // probePath proves a path reaches a node without drawing, appending to steps the steps a
// draw takes. Where pathCheck walks every variant of a choice, it walks the first, // draw takes. Where pathCheck walks every variant of a choice, it walks the first,
// which carriedByAll lets stand for all. // which carriedByAll lets stand for all.
func probePath(n node, tail []string, steps []pathStep) ([]pathStep, error) { func probePath(n node, tail []string, steps []pathStep) ([]pathStep, error) {
@@ -346,7 +346,7 @@ func (t *table) step(tail []string) (column node, child *table, err error) {
return nil, d.Owner(), nil return nil, d.Owner(), nil
} }
// carriedByAll is the choice rule a path that must resolve on every call obeys: // carriedByAll is the choice rule a path that must reach a node on every call obeys:
// the rest of the tail must be one every variant carries. // the rest of the tail must be one every variant carries.
func carriedByAll(c *choice, rest []string) error { func carriedByAll(c *choice, rest []string) error {
if want := strings.Join(rest, "."); !c.shared[want] { if want := strings.Join(rest, "."); !c.shared[want] {
@@ -365,7 +365,7 @@ 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 checkPathResolves(n node, tail []string, level string) error { func checkPathReaches(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
} }
+1 -1
View File
@@ -129,7 +129,7 @@ func TestPathKeyIsUnambiguous(t *testing.T) {
if err == nil || !strings.Contains(err.Error(), `field "a.b" contains "."`) { if err == nil || !strings.Contains(err.Error(), `field "a.b" contains "."`) {
t.Fatalf("New = %v, want the dotted field name rejected", err) t.Fatalf("New = %v, want the dotted field name rejected", err)
} }
// The same data without the dotted key is fine, and the path resolves. // The same data without the dotted key is fine, and the path reaches a node.
f := newGenerator(t, writeData(t, map[string]string{ f := newGenerator(t, writeData(t, map[string]string{
"cat": `{"format":"{a.b}","a":{"format":"{b}","b":"2"}}`, "cat": `{"format":"{a.b}","a":{"format":"{b}","b":"2"}}`,
}), WithSeed(1)) }), WithSeed(1))
+1 -1
View File
@@ -57,7 +57,7 @@ func (t *template) resolveRefs(folder []string, label, category string, root map
if category != "" && head == "/"+category { if category != "" && head == "/"+category {
return refs, 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", label, name) return refs, 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", label, name)
} }
if err := checkPathResolves(target, tail, head); err != nil { if err := checkPathReaches(target, tail, head); err != nil {
return refs, fmt.Errorf("%s: reference {%s}: %w", label, name, err) return refs, fmt.Errorf("%s: reference {%s}: %w", label, name, err)
} }
refs.categories[head] = target refs.categories[head] = target