-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmason.go
More file actions
114 lines (91 loc) · 2.19 KB
/
mason.go
File metadata and controls
114 lines (91 loc) · 2.19 KB
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
package mason
import (
"context"
"net/http"
"github.com/tailbits/mason/model"
)
type groupMap map[string]string
type WebHandler func(ctx context.Context, w http.ResponseWriter, r *http.Request) error
type Middleware interface {
GetHandler(builder Builder) func(WebHandler) WebHandler
}
type GroupMetadata struct {
Summary string
Description string
}
type API struct {
Runtime
registry Registry
models map[string]model.Entity
routeIndex groupMap
groupMeta map[string]GroupMetadata
}
func NewAPI(runtime Runtime) *API {
return &API{
Runtime: runtime,
registry: make(Registry),
models: make(map[string]model.Entity),
routeIndex: make(groupMap),
groupMeta: make(map[string]GroupMetadata),
}
}
func (a *API) NewRouteGroup(name string) *RouteGroup {
return &RouteGroup{
rtm: a,
name: name,
}
}
func (a *API) registerModel(mdl model.Entity) {
a.models[mdl.Name()] = mdl
}
func (a *API) GetModel(name string) (model.Entity, bool) {
e, ok := a.models[name]
return e, ok
}
func (a *API) ForEachOperation(fn func(group string, op Operation)) {
for group, resource := range a.registry {
for _, op := range resource {
fn(group, op)
}
}
}
func (a *API) GroupMetadata(path string) (GroupMetadata, bool) {
meta, ok := a.groupMeta[path]
return meta, ok
}
func (a *API) setGroupSummary(path string, summary string) {
a.updateGroupMetadata(path, func(meta *GroupMetadata) {
meta.Summary = summary
})
}
func (a *API) setGroupDescription(path string, description string) {
a.updateGroupMetadata(path, func(meta *GroupMetadata) {
meta.Description = description
})
}
func (a *API) updateGroupMetadata(path string, update func(*GroupMetadata)) {
if path == "" || update == nil {
return
}
meta := a.groupMeta[path]
update(&meta)
a.groupMeta[path] = meta
}
func registerModel[I, O model.Entity, Q any](api *API, method string, group string, path string, opts ...Option) {
i := model.New[I]()
o := model.New[O]()
q := model.New[Q]()
m := Operation{
Method: method,
Path: path,
Input: i,
Output: o,
QueryParams: q,
}
for _, opt := range opts {
opt(&m)
}
api.registerModel(i)
api.registerModel(o)
api.registerOp(m, group)
}