From 74b8923eccba582298459bfcdd32bc3988010b26 Mon Sep 17 00:00:00 2001 From: nihonglei Date: Sun, 11 Sep 2022 22:12:30 +0800 Subject: [PATCH] this is the trees homework --- web/homework1/route.go | 84 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 15 deletions(-) diff --git a/web/homework1/route.go b/web/homework1/route.go index 315c1ba..de8b8b2 100644 --- a/web/homework1/route.go +++ b/web/homework1/route.go @@ -86,8 +86,26 @@ func (r *router) findRoute(method string, path string) (*matchInfo, bool) { if !ok { return nil, false } + if root.typ == nodeTypeAny { + if root.children == nil && root.starChild == nil && root.paramChild == nil && root.regChild == nil { + break + } + } if matchParam { - mi.addValue(root.path[1:], s) + if root.typ == nodeTypeParam { + mi.addValue(root.paramName, s) + } else { + if root.regExpr == nil { + t4regIndex := strings.Index(root.path, "(") + root.regExpr = regexp.MustCompile(root.path[t4regIndex+1 : len(root.path)-1]) + } + s5res := root.regExpr.FindStringSubmatch(s) + if nil != s5res { + mi.addValue(root.paramName, s5res[0]) + } else { + return nil, false + } + } } } mi.n = root @@ -141,17 +159,25 @@ type node struct { // 第三个返回值 bool 代表是否命中 func (n *node) childOf(path string) (*node, bool, bool) { if n.children == nil { - if n.paramChild != nil { + if n.regChild != nil { + return n.regChild, true, true + } else if n.paramChild != nil { return n.paramChild, true, true + } else if n.starChild != nil { + return n.starChild, false, true } - return n.starChild, false, n.starChild != nil + return nil, false, false } res, ok := n.children[path] if !ok { - if n.paramChild != nil { + if n.regChild != nil { + return n.regChild, true, true + } else if n.paramChild != nil { return n.paramChild, true, true + } else if n.starChild != nil { + return n.starChild, false, true } - return n.starChild, false, n.starChild != nil + return nil, false, false } return res, false, ok } @@ -163,28 +189,56 @@ func (n *node) childOf(path string) (*node, bool, bool) { // 如果没有找到,那么会创建一个新的节点,并且保存在 node 里面 func (n *node) childOrCreate(path string) *node { if path == "*" { + if n.regChild != nil { + panic(fmt.Sprintf("web: 非法路由,已有正则路由。不允许同时注册通配符路由和正则路由 [%s]", path)) + } if n.paramChild != nil { panic(fmt.Sprintf("web: 非法路由,已有路径参数路由。不允许同时注册通配符路由和参数路由 [%s]", path)) } if n.starChild == nil { - n.starChild = &node{path: path} + n.starChild = &node{typ: nodeTypeAny, path: path} } return n.starChild } // 以 : 开头,我们认为是参数路由 if path[0] == ':' { - if n.starChild != nil { - panic(fmt.Sprintf("web: 非法路由,已有通配符路由。不允许同时注册通配符路由和参数路由 [%s]", path)) - } - if n.paramChild != nil { - if n.paramChild.path != path { - panic(fmt.Sprintf("web: 路由冲突,参数路由冲突,已有 %s,新注册 %s", n.paramChild.path, path)) + // 用左括号判断是不是有正则 + regIndex := strings.Index(path, "(") + if regIndex != -1 { + if n.starChild != nil { + panic(fmt.Sprintf("web: 非法路由,已有通配符路由。不允许同时注册通配符路由和正则路由 [%s]", path)) + } + if n.paramChild != nil { + panic(fmt.Sprintf("web: 非法路由,已有路径参数路由。不允许同时注册正则路由和参数路由 [%s]", path)) + } + n.regChild = &node{ + typ: nodeTypeReg, + path: path, + paramName: path[1:regIndex], + //regExpr: regexp.MustCompile(path[t4regIndex : len(path)-1]), } + return n.regChild } else { - n.paramChild = &node{path: path} + if n.starChild != nil { + panic(fmt.Sprintf("web: 非法路由,已有通配符路由。不允许同时注册通配符路由和参数路由 [%s]", path)) + } + if n.regChild != nil { + panic(fmt.Sprintf("web: 非法路由,已有正则路由。不允许同时注册正则路由和参数路由 [%s]", path)) + } + if n.paramChild != nil { + if n.paramChild.path != path { + panic(fmt.Sprintf("web: 路由冲突,参数路由冲突,已有 %s,新注册 %s", n.paramChild.path, path)) + } + } else { + n.paramChild = &node{ + typ: nodeTypeParam, + path: path, + paramName: path[1:], + } + } + return n.paramChild } - return n.paramChild } if n.children == nil { @@ -192,7 +246,7 @@ func (n *node) childOrCreate(path string) *node { } child, ok := n.children[path] if !ok { - child = &node{path: path} + child = &node{typ: nodeTypeStatic, path: path} n.children[path] = child } return child -- Gitee