Give prove, stepInto and columnItems a case per node kind, panicking on the rest

This commit is contained in:
2026-09-29 09:37:32 +02:00
committed by Lillem4n
parent d01c914e7f
commit 16e4f4ebbb
5 changed files with 14 additions and 9 deletions
+3
View File
@@ -138,6 +138,9 @@ func columnItems(n node) (items []*template, nullable bool) {
items = append(items, n) items = append(items, n)
case *nullItem: case *nullItem:
nullable = true nullable = true
case *tableColumn:
default:
panic(internalError("columnItems has no case for node %T", n))
} }
} }
collect(n) collect(n)
+3 -2
View File
@@ -11,8 +11,9 @@ import (
// node is a compiled element of the namespace tree: a folder, choice, null, // node is a compiled element of the namespace tree: a folder, choice, null,
// template, table, column or row. Compiling JSON into these once (see compile) // template, table, column or row. Compiling JSON into these once (see compile)
// means rendering never re-inspects the raw JSON. A new kind needs a // means rendering never re-inspects the raw JSON. A new kind needs a case in
// case in contained, paths, render and renderEdges; each panics on a kind it does not list. // columnItems, contained, paths, prove, render, renderEdges and stepInto; each
// panics on a kind it does not list.
type node interface{ isNode() } type node interface{ isNode() }
// folder is a namespace of named children, built from a directory of JSON files // folder is a namespace of named children, built from a directory of JSON files
+3
View File
@@ -142,6 +142,9 @@ func stepInto(n node, seg string) (node, error) {
} }
case *tableColumn: case *tableColumn:
return nil, fmt.Errorf("no field %q: %q is a column, and a cell holds no fields", seg, n.t.header[n.i]) return nil, fmt.Errorf("no field %q: %q is a column, and a cell holds no fields", seg, n.t.header[n.i])
case *nullItem:
default:
panic(internalError("stepInto has no case for node %T", n))
} }
return nil, fmt.Errorf("no field %q", seg) return nil, fmt.Errorf("no field %q", seg)
} }
-6
View File
@@ -28,10 +28,6 @@ ranking `readSurvey.walk` hardest and all seven the unit they would least modify
This round, in order: This round, in order:
- Give `prove`, `stepInto` and `columnItems` a case per node kind and panic through
`internalError` on the rest, and list every such switch in `node`'s doc: `prove`'s
default tells a typed column reading a bare table that it reads a null, and six seats
found `node` naming four of them.
- Replace `disagreements`' ten keys with the rule they encode: a declared fix holds one - Replace `disagreements`' ten keys with the rule they encode: a declared fix holds one
datatype, a read one is `readTyped` where proven and `readAsText` otherwise, a text one datatype, a read one is `readTyped` where proven and `readAsText` otherwise, a text one
is `otherAsText` beside an unproven read and `declare` otherwise. Six seats could not is `otherAsText` beside an unproven read and `declare` otherwise. Six seats could not
@@ -222,8 +218,6 @@ by a `data-import/` script, as README goal 12 asks.
first in Go's map order. first in Go's map order.
- Report a CRLF rows file holding only its header as having no rows: `parseRows` - Report a CRLF rows file holding only its header as having no rows: `parseRows`
answers "line 2 is empty". answers "line 2 is empty".
- Refuse a bare table read in a typed column with a reason naming the table, once
`prove` has a case per node kind.
- Keep one copy of the selector characters in `data-import/`: `httpmethod.py` and - Keep one copy of the selector characters in `data-import/`: `httpmethod.py` and
`protocol.py` each copy `inSelector`, and `tsv.py`'s `write` enforces neither. `protocol.py` each copy `inSelector`, and `tsv.py`'s `write` enforces neither.
- Refuse two whole reads of one table family in one render, which goal 5 promises is a - Refuse two whole reads of one table family in one render, which goal 5 promises is a
+5 -1
View File
@@ -89,10 +89,14 @@ func (p *valueProof) prove(n node) proven {
v = p.proveTemplate(n) v = p.proveTemplate(n)
case *tableColumn: case *tableColumn:
v = p.proveCells(n) v = p.proveCells(n)
case *table:
v = p.prove(n.rowNode)
case *tableRow: case *tableRow:
v = unproven(fmt.Sprintf("%q renders a row of %s, which is composed text", n.t.formatTemplate.format, n.t.segment)) v = unproven(fmt.Sprintf("%q renders a row of %s, which is composed text", n.t.formatTemplate.format, n.t.segment))
default: case *nullItem:
v = unproven(`it reads a null, which renders "" outside its own column`) v = unproven(`it reads a null, which renders "" outside its own column`)
default:
panic(internalError("prove has no case for node %T", n))
} }
p.memo[n] = v p.memo[n] = v
return v return v