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  }