github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/router.go (about) 1 package courier 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/sirupsen/logrus" 8 ) 9 10 type IServe interface { 11 Serve(router *Router) error 12 } 13 14 func Run(router *Router, serves ...IServe) { 15 errs := make(chan error) 16 17 for i := range serves { 18 s := serves[i] 19 go func() { 20 if err := s.Serve(router); err != nil { 21 errs <- err 22 } 23 }() 24 } 25 26 select { 27 case err := <-errs: 28 logrus.Errorf("%s", err.Error()) 29 } 30 } 31 32 type Router struct { 33 operators []IOperator 34 parent *Router 35 children map[*Router]bool 36 } 37 38 func NewRouter(operators ...IOperator) *Router { 39 return &Router{ 40 operators: operators, 41 } 42 } 43 44 func (router *Router) Register(r *Router) { 45 if router.children == nil { 46 router.children = map[*Router]bool{} 47 } 48 r.parent = router 49 router.children[r] = true 50 } 51 52 func (router *Router) Route() *Route { 53 parent := router.parent 54 operators := router.operators 55 56 for parent != nil { 57 operators = append(parent.operators, operators...) 58 parent = parent.parent 59 } 60 61 return &Route{ 62 last: router.children == nil, 63 Operators: operators, 64 } 65 } 66 67 func (router *Router) Routes() (routes []*Route) { 68 for child := range router.children { 69 route := child.Route() 70 if route.last && len(route.Operators) > 0 { 71 routes = append(routes, route) 72 } 73 if child.children != nil { 74 routes = append(routes, child.Routes()...) 75 } 76 } 77 return 78 } 79 80 type Route struct { 81 Operators []IOperator 82 last bool 83 } 84 85 func (route *Route) EffectiveOperators() (operators []IOperator, operatorTypeNames []string) { 86 for _, operator := range route.Operators { 87 if _, isEmptyOperator := operator.(IEmptyOperator); !isEmptyOperator { 88 operatorType := reflect.TypeOf(operator) 89 modify := "" 90 if stringer, ok := operator.(fmt.Stringer); ok { 91 modify = stringer.String() 92 } 93 if operatorType.Kind() == reflect.Ptr { 94 operatorTypeNames = append(operatorTypeNames, "*"+operatorType.Elem().Name()+modify) 95 } else { 96 operatorTypeNames = append(operatorTypeNames, operatorType.Name()+modify) 97 } 98 operators = append(operators, operator) 99 } 100 } 101 return 102 }