Make great documentation goal 1.2, and plan the README's reorganisation and the nested-template gaps #33
+76
-19
@@ -144,27 +144,84 @@ func columnItems(n node) (items []*template, nullable bool) {
|
|||||||
return items, nullable
|
return items, nullable
|
||||||
}
|
}
|
||||||
|
|
||||||
// disagreement names the fix for two items of one column holding different datatypes. The item to
|
// itemKind is how a column item comes by its datatype: none, read from a typed column, or declared.
|
||||||
// fix declares none unless both do, and is text where the other reads a typed column.
|
type itemKind int
|
||||||
func disagreement(a *template, da DataType, b *template, db DataType) error {
|
|
||||||
fix, has, other, want := a, da, b, db
|
const (
|
||||||
if da != DataTypeString && (a.datatype != DataTypeString || db == DataTypeString) {
|
kindText itemKind = iota
|
||||||
fix, has, other, want = b, db, a, da
|
kindReads
|
||||||
}
|
kindDeclares
|
||||||
proven := (&valueProof{}).proveColumnItem(fix).not[want] == ""
|
)
|
||||||
|
|
||||||
|
func kindOf(t *template) itemKind {
|
||||||
switch {
|
switch {
|
||||||
case fix.datatype != DataTypeString:
|
case t.datatype != DataTypeString:
|
||||||
return fmt.Errorf("its items hold %s and %s; a column holds one datatype", da, db)
|
return kindDeclares
|
||||||
case has != DataTypeString && proven:
|
case itemDatatype(t) != DataTypeString:
|
||||||
return fmt.Errorf("its items hold %s and %s; a column holds one datatype, so %s", da, db, typedAs(fix, want))
|
return kindReads
|
||||||
case has != DataTypeString:
|
|
||||||
return fmt.Errorf("its items hold %s and %s; a column holds one datatype, so to read %q as text, %s", da, db, fix.format, asText(fix))
|
|
||||||
case other.datatype == DataTypeString && !proven:
|
|
||||||
return fmt.Errorf(`item %q is not %s, the datatype item %q takes from the column it reads; to read that column as text, %s`, fix.format, dataTypeNouns[want], other.format, asText(other))
|
|
||||||
case fix.fromString: // an object may carry a weight, which this spelling would drop
|
|
||||||
return fmt.Errorf(`item %q declares no datatype, and a column holds one; write it as {"format":%q,"datatype":%q}`, fix.format, fix.format, want)
|
|
||||||
}
|
}
|
||||||
return fmt.Errorf(`item %q declares no datatype beside one holding %s; a column holds one, so give it "datatype": %q`, fix.format, want, want)
|
return kindText
|
||||||
|
}
|
||||||
|
|
||||||
|
// disagreeing is two items of one column holding different datatypes: fix is the one to change,
|
||||||
|
// and want the datatype of the other.
|
||||||
|
type disagreeing struct {
|
||||||
|
first, second DataType
|
||||||
|
fix, other *template
|
||||||
|
want DataType
|
||||||
|
}
|
||||||
|
|
||||||
|
// disagreementKey is the two items' kinds and whether fix's values prove to hold want.
|
||||||
|
type disagreementKey struct {
|
||||||
|
fix, other itemKind
|
||||||
|
proven bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var disagreements = map[disagreementKey]func(d disagreeing) error{
|
||||||
|
{kindDeclares, kindDeclares, false}: holdOne,
|
||||||
|
{kindDeclares, kindDeclares, true}: holdOne,
|
||||||
|
{kindReads, kindDeclares, false}: readAsText,
|
||||||
|
{kindReads, kindDeclares, true}: readTyped,
|
||||||
|
{kindReads, kindReads, false}: readAsText,
|
||||||
|
{kindReads, kindReads, true}: readTyped,
|
||||||
|
{kindText, kindDeclares, false}: declare,
|
||||||
|
{kindText, kindDeclares, true}: declare,
|
||||||
|
{kindText, kindReads, false}: otherAsText,
|
||||||
|
{kindText, kindReads, true}: declare,
|
||||||
|
}
|
||||||
|
|
||||||
|
// disagreement names the fix for items a and b of one column holding different datatypes, fixing
|
||||||
|
// the one that declares least, a when both declare alike.
|
||||||
|
func disagreement(a *template, da DataType, b *template, db DataType) error {
|
||||||
|
d := disagreeing{first: da, second: db, fix: a, other: b, want: db}
|
||||||
|
if kindOf(b) < kindOf(a) {
|
||||||
|
d.fix, d.other, d.want = b, a, da
|
||||||
|
}
|
||||||
|
proven := (&valueProof{}).proveColumnItem(d.fix).not[d.want] == ""
|
||||||
|
return disagreements[disagreementKey{kindOf(d.fix), kindOf(d.other), proven}](d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func holdOne(d disagreeing) error {
|
||||||
|
return fmt.Errorf("its items hold %s and %s; a column holds one datatype", d.first, d.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTyped(d disagreeing) error {
|
||||||
|
return fmt.Errorf("its items hold %s and %s; a column holds one datatype, so %s", d.first, d.second, typedAs(d.fix, d.want))
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAsText(d disagreeing) error {
|
||||||
|
return fmt.Errorf("its items hold %s and %s; a column holds one datatype, so to read %q as text, %s", d.first, d.second, d.fix.format, asText(d.fix))
|
||||||
|
}
|
||||||
|
|
||||||
|
func otherAsText(d disagreeing) error {
|
||||||
|
return fmt.Errorf(`item %q is not %s, the datatype item %q takes from the column it reads; to read that column as text, %s`, d.fix.format, dataTypeNouns[d.want], d.other.format, asText(d.other))
|
||||||
|
}
|
||||||
|
|
||||||
|
func declare(d disagreeing) error {
|
||||||
|
if d.fix.fromString { // an object may carry a weight, which this spelling would drop
|
||||||
|
return fmt.Errorf(`item %q declares no datatype, and a column holds one; write it as {"format":%q,"datatype":%q}`, d.fix.format, d.fix.format, d.want)
|
||||||
|
}
|
||||||
|
return fmt.Errorf(`item %q declares no datatype beside one holding %s; a column holds one, so give it "datatype": %q`, d.fix.format, d.want, d.want)
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedAs names the spelling giving a column-read item datatype d, keeping the other keys an object
|
// typedAs names the spelling giving a column-read item datatype d, keeping the other keys an object
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ Shape 5.8, Self-sufficiency 5.7), every seat capped by Locality, all nine naming
|
|||||||
|
|
||||||
This round, in order:
|
This round, in order:
|
||||||
|
|
||||||
- Make `disagreement` a table keyed by the two datatypes and the proof, dropping the
|
|
||||||
operand swap: six seats still needed a truth table to see which item it blames.
|
|
||||||
- Move `session.trace` and `renderTrace.repeatDepth` off the render path: they serve
|
- Move `session.trace` and `renderTrace.repeatDepth` off the render path: they serve
|
||||||
`drawfence_test.go` alone.
|
`drawfence_test.go` alone.
|
||||||
- Give `Fake` a local hold set like `FakeRecord`, `RecordTemplate.Fake` and
|
- Give `Fake` a local hold set like `FakeRecord`, `RecordTemplate.Fake` and
|
||||||
|
|||||||
Reference in New Issue
Block a user