github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/gov/keeper/router.go (about) 1 package keeper 2 3 import ( 4 "fmt" 5 "regexp" 6 7 "github.com/fibonacci-chain/fbc/x/gov/types" 8 ) 9 10 var ( 11 _ Router = (*router)(nil) 12 13 isAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString 14 ) 15 16 // Router implements a governance Handler router. 17 // 18 // TODO: Use generic router (ref #3976). 19 type Router interface { 20 AddRoute(r string, h types.Handler) (rtr Router) 21 HasRoute(r string) bool 22 GetRoute(path string) (h types.Handler) 23 Seal() 24 } 25 26 type router struct { 27 routes map[string]types.Handler 28 sealed bool 29 } 30 31 func NewRouter() Router { 32 return &router{ 33 routes: make(map[string]types.Handler), 34 } 35 } 36 37 // Seal seals the router which prohibits any subsequent route handlers to be 38 // added. Seal will panic if called more than once. 39 func (rtr *router) Seal() { 40 if rtr.sealed { 41 panic("router already sealed") 42 } 43 rtr.sealed = true 44 } 45 46 // AddRoute adds a governance handler for a given path. It returns the Router 47 // so AddRoute calls can be linked. It will panic if the router is sealed. 48 func (rtr *router) AddRoute(path string, h types.Handler) Router { 49 if rtr.sealed { 50 panic("router sealed; cannot add route handler") 51 } 52 53 if !isAlphaNumeric(path) { 54 panic("route expressions can only contain alphanumeric characters") 55 } 56 if rtr.HasRoute(path) { 57 panic(fmt.Sprintf("route %s has already been initialized", path)) 58 } 59 60 rtr.routes[path] = h 61 return rtr 62 } 63 64 // HasRoute returns true if the router has a path registered or false otherwise. 65 func (rtr *router) HasRoute(path string) bool { 66 return rtr.routes[path] != nil 67 } 68 69 // GetRoute returns a Handler for a given path. 70 func (rtr *router) GetRoute(path string) types.Handler { 71 if !rtr.HasRoute(path) { 72 panic(fmt.Sprintf("route \"%s\" does not exist", path)) 73 } 74 75 return rtr.routes[path] 76 }