templateUtil.go 2.48 KB
Newer Older
Eric Myhre's avatar
Eric Myhre committed
1 2 3 4
package gengo

import (
	"io"
5
	"strings"
Eric Myhre's avatar
Eric Myhre committed
6 7 8
	"text/template"

	wish "github.com/warpfork/go-wish"
9 10

	ipld "github.com/ipld/go-ipld-prime"
Eric Myhre's avatar
Eric Myhre committed
11 12
)

13
func doTemplate(tmplstr string, w io.Writer, adjCfg *AdjunctCfg, data interface{}) {
14
	tmpl := template.Must(template.New("").
15 16 17 18
		Funcs(template.FuncMap{
			"TypeSymbol":       adjCfg.TypeSymbol,
			"FieldSymbolLower": adjCfg.FieldSymbolLower,
			"FieldSymbolUpper": adjCfg.FieldSymbolUpper,
19
			"MaybeUsesPtr":     adjCfg.MaybeUsesPtr,
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
			"KindPrim": func(k ipld.ReprKind) string {
				switch k {
				case ipld.ReprKind_Map:
					panic("this isn't useful for non-scalars")
				case ipld.ReprKind_List:
					panic("this isn't useful for non-scalars")
				case ipld.ReprKind_Null:
					panic("this isn't useful for null")
				case ipld.ReprKind_Bool:
					return "bool"
				case ipld.ReprKind_Int:
					return "int"
				case ipld.ReprKind_Float:
					return "float64"
				case ipld.ReprKind_String:
					return "string"
				case ipld.ReprKind_Bytes:
					return "[]byte"
				case ipld.ReprKind_Link:
					return "ipld.Link"
				default:
					panic("invalid enumeration value!")
				}
			},
			"add":   func(a, b int) int { return a + b },
			"title": func(s string) string { return strings.Title(s) },
46
		}).
47 48 49 50
		// Seriously consider prepending `{{ $dot := . }}` (or 'top', or something).
		// Or a func into the map that causes `dot` to mean `func() interface{} { return data }`.
		// The number of times that the range feature has a dummy capture line above it is... not reasonable.
		//  (Grep for "/* ranging modifies dot, unhelpfully */" -- empirically, it's over 20 times already.)
51
		Parse(wish.Dedent(tmplstr)))
Eric Myhre's avatar
Eric Myhre committed
52 53 54 55
	if err := tmpl.Execute(w, data); err != nil {
		panic(err)
	}
}
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

// We really need to do some more composable stuff around here.
// Generators should probably be carrying down their own doTemplate methods that curry customizations.
// E.g., map generators would benefit hugely from being able to make a clause for "entTypeStrung", "mTypeStrung", etc.
//
// Open question: how exactly?  Should some of this stuff should be composed by:
//   - composing template fragments;
//   - amending the funcmap;
//   - computing the whole result and injecting it as a string;
//   - ... combinations of the above?
// Adding to the complexity of the question is that sometimes we want to be
//  doing composition inside the output (e.g. DRY by functions in the result,
//   rather than by DRY'ing the templates).
// Best practice to make this evolve nicely is not at all obvious to this author.
//