代码拉取完成,页面将自动刷新
package rest
import (
"fmt"
"regexp/syntax"
"strings"
)
type router struct {
trees map[string]*node
}
type node struct {
path string
//children []*node
/// static node
children map[string]*node
/// wild node 通用匹配。。只有一个
startChild *node
/// 路径参数
parmaChild *node
/// 正则参数
regChild *node
/// 正则表达式
regExpr syntax.Regexp
handler HandleFunc
}
func (n *node) childOrCreate(path string) *node {
if n.children == nil {
n.children = make(map[string]*node)
}
var (
res *node
ok bool
)
if path == "*" {
res, ok = n.startChild, n.startChild != nil
} else if strings.HasPrefix(path, ":") { // 路径参数
res, ok = n.parmaChild, n.parmaChild != nil
} else {
res, ok = n.children[path]
}
if !ok {
res = &node{path: path}
if path == "*" {
if n.parmaChild != nil {
panic(fmt.Sprintf("路径[%s]已有参数路由", n.path))
}
n.startChild = res
} else if strings.HasPrefix(path, ":") {
if n.startChild != nil && n.startChild.handler != nil {
panic(fmt.Sprintf("路径[%s]已有通配符路由", n.path))
}
n.parmaChild = res
} else {
n.children[path] = res
}
}
return res
}
/*
childOf
第一个返回值为node
第二个返回值为是否是路径参数
第三个返回值为是否匹配到
*/
func (n *node) childOf(path string) (*node, bool, bool) {
if path == "/" {
return n, false, true
}
path = strings.Trim(path, "/")
segs := strings.Split(path, "/")
var (
child = n
)
for _, seg := range segs {
var (
r *node
ok bool
)
r, ok = child.children[seg]
if !ok {
if child.parmaChild != nil {
return child.parmaChild, true, true
}
r, ok = child.startChild, child.startChild != nil
}
if !ok {
return nil, false, false
}
child = r
}
return child, false, true
}
func newRouter() *router {
return &router{trees: make(map[string]*node)}
}
func (r *router) addRoute(method string, path string, handleFunc HandleFunc) {
if path == "" {
panic("rest : path can not be nil")
}
if !strings.HasPrefix(path, "/") {
panic("rest : path must start with /")
}
if path != "/" && strings.HasSuffix(path, "/") {
panic("rest : path cannot be end with /")
}
if strings.Contains(path, "//") {
panic("rest : path cannot contain //")
}
root, ok := r.trees[method]
if !ok {
root = &node{
path: "/",
}
r.trees[method] = root
}
path = path[1:]
paths := strings.Split(path, "/")
for _, e := range paths {
if len(e) == 0 {
continue
}
child := root.childOrCreate(e)
root = child
}
if root.handler != nil {
panic(fmt.Sprintf("rest:路由冲突:[%s]重复注册", root.path))
}
root.handler = handleFunc
}
func (r *router) findRoute(method string, path string) (*matchInfo, bool) {
root, ok := r.trees[method]
if !ok {
return nil, false
}
if path == "/" {
return &matchInfo{
n: root,
params: nil,
}, true
}
path = strings.Trim(path, "/")
segs := strings.Split(path, "/")
params := make(map[string]string)
for _, seg := range segs {
n, isParamsRoute, ok := root.childOf(seg)
if !ok {
return nil, false
}
if isParamsRoute {
params[n.path[1:]] = seg
}
root = n
}
//n, isParamsRoute, ok := root.childOf(path)
//if !ok {
// return nil, false
//}
//
//if isParamsRoute {
// return &matchInfo{
// n: n,
// params: map[string]string{},
// }, true
//}
return &matchInfo{
n: root,
params: params,
}, true
}
type matchInfo struct {
n *node
params map[string]string
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。