/
router.go
103 lines (88 loc) · 2.1 KB
/
router.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
package courier
import (
"fmt"
"github.com/eden-framework/context"
"reflect"
"github.com/sirupsen/logrus"
)
type IServe interface {
Serve(ctx *context.WaitStopContext, router *Router) error
}
func Run(ctx *context.WaitStopContext, router *Router, serves ...IServe) {
errs := make(chan error)
for i := range serves {
s := serves[i]
go func() {
if err := s.Serve(ctx, router); err != nil {
errs <- err
}
}()
}
select {
case err := <-errs:
logrus.Errorf("%s", err.Error())
}
}
type Router struct {
operators []IOperator
parent *Router
children map[*Router]bool
}
func NewRouter(operators ...IOperator) *Router {
return &Router{
operators: operators,
}
}
func (router *Router) Register(r *Router) {
if router.children == nil {
router.children = map[*Router]bool{}
}
r.parent = router
router.children[r] = true
}
func (router *Router) Route() *Route {
parent := router.parent
operators := router.operators
for parent != nil {
operators = append(parent.operators, operators...)
parent = parent.parent
}
return &Route{
last: router.children == nil,
Operators: operators,
}
}
func (router *Router) Routes() (routes []*Route) {
for child := range router.children {
route := child.Route()
if route.last && len(route.Operators) > 0 {
routes = append(routes, route)
}
if child.children != nil {
routes = append(routes, child.Routes()...)
}
}
return
}
type Route struct {
Operators []IOperator
last bool
}
func (route *Route) EffectiveOperators() (operators []IOperator, operatorTypeNames []string) {
for _, operator := range route.Operators {
if _, isEmptyOperator := operator.(IEmptyOperator); !isEmptyOperator {
operatorType := reflect.TypeOf(operator)
modify := ""
if stringer, ok := operator.(fmt.Stringer); ok {
modify = stringer.String()
}
if operatorType.Kind() == reflect.Ptr {
operatorTypeNames = append(operatorTypeNames, "*"+operatorType.Elem().Name()+modify)
} else {
operatorTypeNames = append(operatorTypeNames, operatorType.Name()+modify)
}
operators = append(operators, operator)
}
}
return
}