/
mapgen.go
111 lines (90 loc) · 2.49 KB
/
mapgen.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
package mapgen
import (
"bytes"
"os"
"path/filepath"
"regexp"
"strings"
"text/template"
)
type MapGen struct {
path string
packageName string
typeName string
targets []string
}
func NewMapGen(path, packageName, typeName string, targets []string) MapGen {
return MapGen{
path: path,
packageName: packageName,
typeName: typeName,
targets: targets,
}
}
func (mg MapGen) Generate() error {
filename := filepath.Join(mg.path, strings.ToLower(mg.typeName)+"-mapping.go")
if _, err := os.Stat(filename); err == nil {
os.Remove(filename)
}
data := mapGenTplData{
PackageName: mg.packageName,
TypeName: mg.typeName,
Targets: make(map[string]string),
}
removeSpecialCharsRegex := regexp.MustCompile("[^a-zA-Z0-9]+")
for _, targetType := range mg.targets {
typeName := targetType
typeNameBytes := []byte(typeName)
typeNameBytes = removeSpecialCharsRegex.ReplaceAll(typeNameBytes, []byte(""))
// set the first character to uppercase
typeNameBytes[0] = bytes.ToUpper(typeNameBytes[0:1])[0]
typeName = string(typeNameBytes)
data.Targets[targetType] = typeName
}
file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0777)
if err != nil {
return err
}
err = mapGenTpl.Execute(file, data)
return err
}
type mapGenTplData struct {
PackageName string
TypeName string
Targets map[string]string
}
var mapGenTpl *template.Template = template.Must(template.New("mapGen").Parse(`package {{.PackageName}}
/*
DO NOT EDIT THIS FILE... or your changes will be overwritten.
This file was generated by mapgen. (https://github.com/jclohmann/mapgen)
*/
type {{.TypeName}}Slice []{{.TypeName}}
{{$outer := .}}
{{range $targetType, $targetName := .Targets}}
type {{$outer.TypeName}}MapTo{{$targetName}}Func func({{$outer.TypeName}}) {{$targetType}}
func (slice {{$outer.TypeName}}Slice) MapTo{{$targetName}}(fn {{$outer.TypeName}}MapTo{{$targetName}}Func) []{{$targetType}} {
var output []{{$targetType}}
for _, item := range slice {
out := fn(item)
output = append(output, out)
}
return output
}
{{end}}
type {{.TypeName}}FilterFunc func({{.TypeName}}) bool
func (slice {{.TypeName}}Slice) Filter(fn {{.TypeName}}FilterFunc) {{.TypeName}}Slice {
var output {{.TypeName}}Slice
for _, item := range slice {
if fn(item) {
output = append(output, item)
}
}
return output
}
type {{.TypeName}}EachFunc func({{.TypeName}})
func (slice {{.TypeName}}Slice) Each(fn {{.TypeName}}EachFunc) {
for _, item := range slice {
fn(item)
}
}
`))