| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- package app
- import (
- "reflect"
- "regexp"
- "sync"
- )
- var (
- routes = makeRouter()
- )
- // Route associates the type of the given component to the given path.
- //
- // When a page is requested and matches the route, a new instance of the given
- // component is created before being displayed.
- func Route(path string, c Composer) {
- routes.route(path, c)
- }
- // RouteWithRegexp associates the type of the given component to the given
- // regular expression pattern.
- //
- // Patterns use the Go standard regexp format.
- //
- // When a page is requested and matches the pattern, a new instance of the given
- // component is created before being displayed.
- func RouteWithRegexp(pattern string, c Composer) {
- routes.routeWithRegexp(pattern, c)
- }
- type router struct {
- mu sync.RWMutex
- routes map[string]reflect.Type
- routesWithRegexp []regexpRoute
- }
- func makeRouter() router {
- return router{
- routes: make(map[string]reflect.Type),
- }
- }
- func (r *router) route(path string, c Composer) {
- r.mu.Lock()
- defer r.mu.Unlock()
- r.routes[path] = reflect.TypeOf(c)
- }
- func (r *router) routeWithRegexp(pattern string, c Composer) {
- r.mu.Lock()
- defer r.mu.Unlock()
- r.routesWithRegexp = append(r.routesWithRegexp, regexpRoute{
- regexp: regexp.MustCompile(pattern),
- compoType: reflect.TypeOf(c),
- })
- }
- func (r *router) createComponent(path string) (Composer, bool) {
- r.mu.RLock()
- defer r.mu.RUnlock()
- compoType, isRouted := r.routes[path]
- if !isRouted {
- for _, rwr := range r.routesWithRegexp {
- if rwr.regexp.MatchString(path) {
- compoType = rwr.compoType
- isRouted = true
- break
- }
- }
- }
- if !isRouted {
- return nil, false
- }
- compo := reflect.New(compoType.Elem()).Interface().(Composer)
- return compo, true
- }
- func (r *router) len() int {
- return len(r.routes) + len(r.routesWithRegexp)
- }
- type regexpRoute struct {
- regexp *regexp.Regexp
- compoType reflect.Type
- }
|