forked from 99designs/gqlgen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
templates.go
139 lines (120 loc) · 2.55 KB
/
templates.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
//go:generate go run ./inliner/inliner.go
package templates
import (
"bytes"
"fmt"
"sort"
"strconv"
"strings"
"text/template"
"unicode"
)
func Run(name string, tpldata interface{}) (*bytes.Buffer, error) {
t := template.New("").Funcs(template.FuncMap{
"ucFirst": ucFirst,
"lcFirst": lcFirst,
"quote": strconv.Quote,
"rawQuote": rawQuote,
"toCamel": ToCamel,
"dump": dump,
"prefixLines": prefixLines,
})
for filename, data := range data {
_, err := t.New(filename).Parse(data)
if err != nil {
panic(err)
}
}
buf := &bytes.Buffer{}
err := t.Lookup(name).Execute(buf, tpldata)
if err != nil {
return nil, err
}
return buf, nil
}
func ucFirst(s string) string {
if s == "" {
return ""
}
r := []rune(s)
r[0] = unicode.ToUpper(r[0])
return string(r)
}
func lcFirst(s string) string {
if s == "" {
return ""
}
r := []rune(s)
r[0] = unicode.ToLower(r[0])
return string(r)
}
func isDelimiter(c rune) bool {
return c == '-' || c == '_' || unicode.IsSpace(c)
}
func ToCamel(s string) string {
buffer := make([]rune, 0, len(s))
upper := true
lastWasUpper := false
for _, c := range s {
if isDelimiter(c) {
upper = true
continue
}
if !lastWasUpper && unicode.IsUpper(c) {
upper = true
}
if upper {
buffer = append(buffer, unicode.ToUpper(c))
} else {
buffer = append(buffer, unicode.ToLower(c))
}
upper = false
lastWasUpper = unicode.IsUpper(c)
}
return string(buffer)
}
func rawQuote(s string) string {
return "`" + strings.Replace(s, "`", "`+\"`\"+`", -1) + "`"
}
func dump(val interface{}) string {
switch val := val.(type) {
case int:
return strconv.Itoa(val)
case float64:
return fmt.Sprintf("%f", val)
case string:
return strconv.Quote(val)
case bool:
return strconv.FormatBool(val)
case nil:
return "nil"
case []interface{}:
var parts []string
for _, part := range val {
parts = append(parts, dump(part))
}
return "[]interface{}{" + strings.Join(parts, ",") + "}"
case map[string]interface{}:
buf := bytes.Buffer{}
buf.WriteString("map[string]interface{}{")
var keys []string
for key := range val {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
data := val[key]
buf.WriteString(strconv.Quote(key))
buf.WriteString(":")
buf.WriteString(dump(data))
buf.WriteString(",")
}
buf.WriteString("}")
return buf.String()
default:
panic(fmt.Errorf("unsupported type %T", val))
}
}
func prefixLines(prefix, s string) string {
return prefix + strings.Replace(s, "\n", "\n"+prefix, -1)
}