-
-
Notifications
You must be signed in to change notification settings - Fork 182
/
state.go
231 lines (207 loc) · 4.45 KB
/
state.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
package controller
import (
"strconv"
"strings"
"github.com/livebud/bud/internal/imports"
"github.com/livebud/bud/package/di"
"github.com/livebud/bud/package/parser"
"github.com/matthewmueller/gotext"
"github.com/matthewmueller/text"
)
type State struct {
Imports []*imports.Import
Controller *Controller
Providers []*di.Provider
}
// Controller is the target controller state
type Controller struct {
Name string
Pascal string
JSON string
Path string // Path to controller without action dir
Route string
Actions []*Action
Controllers []*Controller
}
func (c *Controller) Last() Name {
names := strings.Split(c.Name, " ")
return Name(names[len(names)-1])
}
type Name string
func (n Name) Pascal() string {
return gotext.Pascal(string(n))
}
// Action is the target action state
type Action struct {
Name string
Pascal string
Camel string
Short string
View *View
Key string // Key is an extension-less path
Route string // Route to this action
Redirect string
Method string
Provider *di.Provider
Params []*ActionParam
HandlerFunc bool
Input string
Results ActionResults
RespondJSON bool
RespondHTML bool
PropsKey string
}
// View struct
type View struct {
Route string
}
// ActionParam struct
type ActionParam struct {
Name string
Pascal string
Snake string
Type string
Kind string
Variable string
Tag string
}
func (ap *ActionParam) IsContext() bool {
return ap.Type == "context.Context"
}
// ActionResults fn
type ActionResults []*ActionResult
// Set helper
func (results ActionResults) Set() string {
if len(results) == 0 {
return ""
}
variables := make([]string, len(results))
for i, output := range results {
variables[i] = output.Variable
}
resultString := strings.Join(variables, ", ")
// Tack on the operator
return resultString + " := "
}
// Result expression if there is one
func (results ActionResults) Result() string {
var list ActionResults
for _, result := range results {
if result.IsError {
continue
}
list = append(list, result)
}
// Return nothing
if len(list) == 0 {
return ""
}
if len(list) == 1 {
return list[0].Variable
}
if list.isArray() {
out := "[]interface{}{"
for _, result := range list {
out += result.Variable
out += ","
}
out += "}"
return out
}
if list.isObject() {
out := "map[string]interface{}{"
for _, result := range list {
out += strconv.Quote(result.Snake)
out += ": "
out += result.Variable
out += ","
}
out += "}"
return out
}
return ""
}
func (results ActionResults) propsKey() string {
for _, result := range results {
if result.IsError {
continue
} else if result.Named {
return result.Name
}
dataType := strings.TrimPrefix(result.Type, "[]*")
if isList(result.Type) {
// e.g. []*UserStory => userStories
return gotext.Camel(text.Plural(dataType))
}
// e.g. *UserStory => userStory
return gotext.Camel(dataType)
}
return ""
}
func isList(dataType string) bool {
return strings.HasPrefix(dataType, "[]") ||
strings.HasPrefix(dataType, "map")
}
func (results ActionResults) ViewResult() string {
propsKey := results.propsKey()
out := new(strings.Builder)
out.WriteString(`map[string]interface{}{`)
if propsKey != "" {
out.WriteString(strconv.Quote(propsKey))
out.WriteString(":")
out.WriteString(results.Result())
}
out.WriteString(`},`)
return out.String()
}
func (results ActionResults) isArray() bool {
for _, result := range results {
if !result.Named {
return true
}
}
return false
}
func (results ActionResults) isObject() bool {
for _, result := range results {
if result.Pascal == "" {
return false
}
}
return true
}
// Error expression if there is one
func (results ActionResults) Error() string {
for _, result := range results {
if result.IsError {
return result.Variable
}
}
return ""
}
// Error expression is only return
func (results ActionResults) IsOnlyError() bool {
return len(results) == 1 && results[0].IsError
}
// ActionResult struct
type ActionResult struct {
Name string
Pascal string
Named bool
Snake string
Type string
Kind parser.Kind
Variable string
IsError bool
Fields []*ActionResultField
Methods []*ActionResultMethod
}
// ActionResultField struct
type ActionResultField struct {
Name string
Type string
Tag string
}
// ActionResultMethod struct
type ActionResultMethod struct {
}