-
Notifications
You must be signed in to change notification settings - Fork 0
/
simple_typewriter.go
139 lines (117 loc) · 3.81 KB
/
simple_typewriter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package predicate
import (
"fmt"
"io"
"strings"
"github.com/clipperhouse/gen/typewriter"
"github.com/clipperhouse/inflect"
)
const Common = "Common"
// A simple typewriter is intended to be a very simple bridge between a template set
// and the typewriter interface expected by clipperhouse/gen. It is appropriate iff
// you have a 1:1 correspondence between the names of the templates and the items you
// wish to generate.
type SimpleTypewriter struct {
name string
itemsForTypeName map[string][]string
templateSet typewriter.TemplateSet
headersForItemType map[string][]string
}
func NewSimpleTypewriter(name string) *SimpleTypewriter {
return &SimpleTypewriter{
name: name,
itemsForTypeName: make(map[string][]string),
headersForItemType: make(map[string][]string),
}
}
// --------------------- Configuration ---------------------
func (tw *SimpleTypewriter) WithTemplates(templates typewriter.TemplateSet) *SimpleTypewriter {
tw.templateSet = templates
return tw
}
func (tw *SimpleTypewriter) WithHeader(headerText string) *SimpleTypewriter {
return tw.WithItemHeader(Common, headerText)
}
func (tw *SimpleTypewriter) WithItemHeader(itemTag string, headerText string) *SimpleTypewriter {
tw.headersForItemType[itemTag] = append(tw.headersForItemType[itemTag], headerText)
return tw
}
// --------------------- Implementation ---------------------
func plural(input string) (result string) {
result = inflect.Pluralize(input)
if result == input {
result += "s"
}
return
}
func (tw *SimpleTypewriter) itemsToGenerate(names []string) []string {
items := make([]string, 0, len(names)+1)
for _, name := range names {
if tw.templateSet.Contains(name) {
items = append(items, name)
}
}
if len(items) > 0 && tw.templateSet.Contains(Common) {
return append([]string{Common}, items...)
} else {
return items
}
}
func (tw *SimpleTypewriter) Name() string {
return tw.name
}
// Validates that the tag on the gen type has correctly instructed this
// typewriter to generate code. If the first return value is false, then
// none of the write methods are called.
func (tw *SimpleTypewriter) Validate(twt typewriter.Type) (bool, error) {
tag, found, err := twt.Tags.ByName(plural(tw.name))
if !found || err != nil {
return false, err
}
items := tw.itemsToGenerate(tag.Items)
fmt.Printf("%s: items for %s: %v\n", tw.Name(), twt.String(), items)
if len(items) == 0 {
// not an error, but irrelevant to generation
return false, nil
}
tw.itemsForTypeName[twt.String()] = items
return true, nil
}
// Write headersForItemType for the generated file. This would include licensing, credits
// or anything else that you wanted to put in there. This can depend upon the
// items selected.
func (tw *SimpleTypewriter) WriteHeader(wrt io.Writer, twt typewriter.Type) {
for _, item := range tw.itemsForTypeName[twt.String()] {
tw.writeHeaderForItem(item, wrt)
}
}
func (tw *SimpleTypewriter) writeHeaderForItem(itemName string, wrt io.Writer) {
headers, present := tw.headersForItemType[itemName]
if !present {
return
}
wrt.Write([]byte(strings.Join(headers, "\n")))
}
// Return the imports for the generated file. The gen library handles writing the actual
// output.
func (tw *SimpleTypewriter) Imports(twt typewriter.Type) (result []typewriter.ImportSpec) {
// none, not handled just yet
return result
}
// Write the actual body.
func (tw *SimpleTypewriter) WriteBody(wrt io.Writer, twt typewriter.Type) {
for _, item := range tw.itemsForTypeName[twt.String()] {
tw.writeTemplateBody(item, wrt, twt)
}
return
}
func (tw *SimpleTypewriter) writeTemplateBody(templateName string, wrt io.Writer, twt typewriter.Type) {
template, err := tw.templateSet.Get(templateName)
if err != nil {
fmt.Println(err)
}
err = template.Execute(wrt, twt)
if err != nil {
fmt.Println(err)
}
}