Commit ef17e649 authored by Eric Myhre's avatar Eric Myhre

Extract and DRY AssignNull method for most types.

This one turns out to be different betweens scalars and recursives,
if in a small (and fortunately consistent) way.
parent 9737070b
......@@ -109,14 +109,46 @@ func emitNodeAssemblerType_scalar(w io.Writer, adjCfg *AdjunctCfg, data interfac
`, w, adjCfg, data)
}
func emitNodeAssemblerMethodAssignNull_scalar(w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.{{ .ReprKind.String | title }}Assembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
}
panic("unreachable")
}
`, w, adjCfg, data)
}
// almost the same as the variant for scalars, but also has to check for midvalue state.
func emitNodeAssemblerMethodAssignNull_recursive(w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.{{ .ReprKind.String | title }}Assembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
case midvalue:
panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
}
panic("unreachable")
}
`, w, adjCfg, data)
}
/*
Some things that might make it easier to DRY stuff, if they were standard in the 'data' obj:
- KindUpper
- e.g. makes it possible to hoist out 'AssignNull', which needs to refer to a kind-particular mixin type.
- also usable for to make 'AssignNode' hoistable for scalars.
- works purely textually for scalars, conveniently.
- maps and lists would need to branch entirely for the bottom half of the method.
- IsRepr
- ...? Somewhat unsure on this one; many different ways to cut this.
- Would be used as `{{if .IsRepr}}Repr{{end}}` in some cases, and `{{if .IsRepr}}__Repr{{end}}` in others...
......
......@@ -150,20 +150,7 @@ func (g intBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
emitNodeAssemblerType_scalar(w, g.AdjCfg, g)
}
func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.IntAssembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
}
panic("unreachable")
}
`, w, g.AdjCfg, g)
emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g)
}
func (g intBuilderGenerator) EmitNodeAssemblerMethodAssignInt(w io.Writer) {
// This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated.
......
......@@ -254,23 +254,7 @@ func (g listBuilderGenerator) EmitNodeAssemblerMethodBeginList(w io.Writer) {
`, w, g.AdjCfg, g)
}
func (g listBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
// DRY: this seems awfully similar -- almost exact, even -- *even* to anything mapoid (except the mixin type name contains 'List' instead of 'Map').
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.ListAssembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
case midvalue:
panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
}
panic("unreachable")
}
`, w, g.AdjCfg, g)
emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g)
}
func (g listBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) {
// AssignNode goes through three phases:
......
......@@ -332,24 +332,7 @@ func (g mapBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) {
`, w, g.AdjCfg, g)
}
func (g mapBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
// DRY: this seems awfully similar -- almost exact, even -- amongst anything mapoid. Can we extract?
// Might even be something we can turn into a util function, not just a template dry. Only parameters are '*m', kind mixin, and type name.
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.MapAssembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
case midvalue:
panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
}
panic("unreachable")
}
`, w, g.AdjCfg, g)
emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g)
}
func (g mapBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) {
// AssignNode goes through three phases:
......
......@@ -160,20 +160,7 @@ func (g stringBuilderGenerator) EmitNodeAssemblerType(w io.Writer) {
emitNodeAssemblerType_scalar(w, g.AdjCfg, g)
}
func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.StringAssembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
}
panic("unreachable")
}
`, w, g.AdjCfg, g)
emitNodeAssemblerMethodAssignNull_scalar(w, g.AdjCfg, g)
}
func (g stringBuilderGenerator) EmitNodeAssemblerMethodAssignString(w io.Writer) {
// This method contains a branch to support MaybeUsesPtr because new memory may need to be allocated.
......
......@@ -309,22 +309,7 @@ func (g structBuilderGenerator) EmitNodeAssemblerMethodBeginMap(w io.Writer) {
`, w, g.AdjCfg, g)
}
func (g structBuilderGenerator) EmitNodeAssemblerMethodAssignNull(w io.Writer) {
doTemplate(`
func (na *_{{ .Type | TypeSymbol }}__Assembler) AssignNull() error {
switch *na.m {
case allowNull:
*na.m = schema.Maybe_Null
return nil
case schema.Maybe_Absent:
return mixins.MapAssembler{"{{ .PkgName }}.{{ .TypeName }}"}.AssignNull()
case schema.Maybe_Value, schema.Maybe_Null:
panic("invalid state: cannot assign into assembler that's already finished")
case midvalue:
panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!")
}
panic("unreachable")
}
`, w, g.AdjCfg, g)
emitNodeAssemblerMethodAssignNull_recursive(w, g.AdjCfg, g)
}
func (g structBuilderGenerator) EmitNodeAssemblerMethodAssignNode(w io.Writer) {
// AssignNode goes through three phases:
......
......@@ -68,6 +68,9 @@ type IntAssemblerTraits struct {
AppliedPrefix string // see doc in kindAssemblerTraitsGenerator
}
func (IntAssemblerTraits) ReprKind() ipld.ReprKind {
return ipld.ReprKind_Int
}
func (g IntAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) {
kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, ipld.ReprKind_Int}.emitNodeAssemblerMethodBeginMap(w)
}
......
......@@ -67,6 +67,9 @@ type ListAssemblerTraits struct {
AppliedPrefix string // see doc in kindAssemblerTraitsGenerator
}
func (ListAssemblerTraits) ReprKind() ipld.ReprKind {
return ipld.ReprKind_List
}
func (g ListAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) {
kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, ipld.ReprKind_List}.emitNodeAssemblerMethodBeginMap(w)
}
......
......@@ -63,6 +63,9 @@ type MapAssemblerTraits struct {
AppliedPrefix string // see doc in kindAssemblerTraitsGenerator
}
func (MapAssemblerTraits) ReprKind() ipld.ReprKind {
return ipld.ReprKind_Map
}
func (g MapAssemblerTraits) EmitNodeAssemblerMethodBeginList(w io.Writer) {
kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, ipld.ReprKind_Map}.emitNodeAssemblerMethodBeginList(w)
}
......
......@@ -68,6 +68,9 @@ type StringAssemblerTraits struct {
AppliedPrefix string // see doc in kindAssemblerTraitsGenerator
}
func (StringAssemblerTraits) ReprKind() ipld.ReprKind {
return ipld.ReprKind_String
}
func (g StringAssemblerTraits) EmitNodeAssemblerMethodBeginMap(w io.Writer) {
kindAssemblerTraitsGenerator{g.PkgName, g.TypeName, g.AppliedPrefix, ipld.ReprKind_String}.emitNodeAssemblerMethodBeginMap(w)
}
......
......@@ -2,6 +2,7 @@ package gengo
import (
"io"
"strings"
"text/template"
wish "github.com/warpfork/go-wish"
......@@ -15,6 +16,7 @@ func doTemplate(tmplstr string, w io.Writer, adjCfg *AdjunctCfg, data interface{
"FieldSymbolUpper": adjCfg.FieldSymbolUpper,
"MaybeUsesPtr": adjCfg.MaybeUsesPtr,
"add": func(a, b int) int { return a + b },
"title": func(s string) string { return strings.Title(s) },
}).
// Seriously consider prepending `{{ $dot := . }}` (or 'top', or something).
// Or a func into the map that causes `dot` to mean `func() interface{} { return data }`.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment