github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/router/route.go (about)

     1  package router
     2  
     3  import (
     4  	"github.com/volts-dev/volts/registry"
     5  )
     6  
     7  const (
     8  	Normal RoutePosition = iota
     9  	Before
    10  	After
    11  	Replace // the route replace origin
    12  )
    13  
    14  type RoutePosition byte
    15  
    16  func (self RoutePosition) String() string {
    17  	return [...]string{"Normal", "Before", "After", "Replace"}[self]
    18  }
    19  
    20  type (
    21  
    22  	// route 路,表示一个Link 连接地址"../webgo/"
    23  	// 提供基础数据参数供Handler处理
    24  	route struct {
    25  		group           *TGroup
    26  		Id              int           // 用于定位
    27  		Path            string        // !NOTE! Path存储路由绑定的URL 网络路径
    28  		PathDelimitChar byte          // URL分割符 "/"或者"."
    29  		FilePath        string        // 短存储路径
    30  		Position        RoutePosition //
    31  		handlers        []*handler    // 最终处理器 合并主处理器+次处理器 代理处理器
    32  		Methods         []string      // 方法
    33  		Host            []string      //
    34  		Url             *TUrl         // 提供Restful 等Controller.Action
    35  		Action          string        // 动作名称[包含模块名,动作名] "Model.Action", "/index.html","/filename.png"
    36  	}
    37  )
    38  
    39  var idQueue int = 0 //id 自动递增值
    40  
    41  func RouteToEndpiont(r *route) *registry.Endpoint {
    42  	ep := &registry.Endpoint{
    43  		//Name: r.
    44  		Method: r.Methods,
    45  		Path:   r.Path,
    46  		Host:   r.Host,
    47  		//Metadata: make(map[string]string),
    48  	}
    49  	//ep.Metadata["Path"] = r.Path
    50  	//ep.Metadata["FilePath"] = r.FilePath
    51  	//ep.Metadata["Type"] = r.Type.String()
    52  
    53  	return ep
    54  }
    55  
    56  func EndpiontToRoute(ep *registry.Endpoint) *route {
    57  	r := newRoute(
    58  		nil,
    59  		ep.Method,
    60  		nil,
    61  		ep.Path,
    62  		"",
    63  		"",
    64  		"",
    65  	)
    66  
    67  	return r
    68  }
    69  
    70  func newRoute(group *TGroup, methods []string, url *TUrl, path, filePath, name, action string) *route {
    71  	r := &route{
    72  		group:           group,
    73  		Id:              idQueue + 1,
    74  		Url:             url,
    75  		Path:            path,
    76  		PathDelimitChar: '/',
    77  		FilePath:        filePath,
    78  		Action:          action, //
    79  		Methods:         methods,
    80  		handlers:        make([]*handler, 0),
    81  	}
    82  
    83  	if url != nil {
    84  		r.Path = url.Path
    85  	}
    86  
    87  	return r
    88  }
    89  
    90  func (self *route) Group() *TGroup {
    91  	return self.group
    92  }
    93  
    94  // TODO 管理Ctrl 顺序 before center after
    95  // 根据不同Action 名称合并Ctrls
    96  func (self *route) CombineHandler(from *route) {
    97  	switch from.Position {
    98  	case Before:
    99  		self.handlers = append(from.handlers, self.handlers...)
   100  	case After:
   101  		self.handlers = append(self.handlers, from.handlers...)
   102  	default:
   103  		// 替换路由会直接替换 主控制器 但不会影响其他Hook 进来的控制器
   104  		self.handlers = from.handlers
   105  	}
   106  }
   107  
   108  // 剥离目标路由
   109  // TODO 优化
   110  func (self *route) StripHandler(target *route) {
   111  	srvs := make([]*registry.Service, 0)
   112  	var match bool
   113  	for _, ctr := range self.handlers {
   114  		if ctr.Type != LocalHandler {
   115  			for _, srv := range ctr.Services {
   116  				match = false
   117  				for _, hd := range target.handlers {
   118  					for _, s := range hd.Services {
   119  						if !srv.Equal(s) {
   120  							match = true
   121  							break
   122  						}
   123  					}
   124  				}
   125  
   126  				if !match {
   127  					srvs = append(srvs, srv)
   128  				}
   129  			}
   130  
   131  			ctr.Services = srvs
   132  		}
   133  	}
   134  }