mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-02-03 00:38:40 +08:00
parent
edf743cd72
commit
491213afb8
@ -1,6 +1,9 @@
|
||||
package search
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
colon = ':'
|
||||
@ -8,16 +11,16 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrDupItem means adding duplicated item.
|
||||
ErrDupItem = errors.New("duplicated item")
|
||||
// ErrDupSlash means item is started with more than one slash.
|
||||
ErrDupSlash = errors.New("duplicated slash")
|
||||
// ErrEmptyItem means adding empty item.
|
||||
ErrEmptyItem = errors.New("empty item")
|
||||
// ErrInvalidState means search tree is in an invalid state.
|
||||
ErrInvalidState = errors.New("search tree is in an invalid state")
|
||||
// ErrNotFromRoot means path is not starting with slash.
|
||||
ErrNotFromRoot = errors.New("path should start with /")
|
||||
// errDupItem means adding duplicated item.
|
||||
errDupItem = errors.New("duplicated item")
|
||||
// errDupSlash means item is started with more than one slash.
|
||||
errDupSlash = errors.New("duplicated slash")
|
||||
// errEmptyItem means adding empty item.
|
||||
errEmptyItem = errors.New("empty item")
|
||||
// errInvalidState means search tree is in an invalid state.
|
||||
errInvalidState = errors.New("search tree is in an invalid state")
|
||||
// errNotFromRoot means path is not starting with slash.
|
||||
errNotFromRoot = errors.New("path should start with /")
|
||||
|
||||
// NotFound is used to hold the not found result.
|
||||
NotFound Result
|
||||
@ -58,14 +61,22 @@ func NewTree() *Tree {
|
||||
// Add adds item to associate with route.
|
||||
func (t *Tree) Add(route string, item interface{}) error {
|
||||
if len(route) == 0 || route[0] != slash {
|
||||
return ErrNotFromRoot
|
||||
return errNotFromRoot
|
||||
}
|
||||
|
||||
if item == nil {
|
||||
return ErrEmptyItem
|
||||
return errEmptyItem
|
||||
}
|
||||
|
||||
return add(t.root, route[1:], item)
|
||||
err := add(t.root, route[1:], item)
|
||||
switch err {
|
||||
case errDupItem:
|
||||
return duplicatedItem(route)
|
||||
case errDupSlash:
|
||||
return duplicatedSlash(route)
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Search searches item that associates with given route.
|
||||
@ -141,7 +152,7 @@ func (nd *node) getChildren(route string) map[string]*node {
|
||||
func add(nd *node, route string, item interface{}) error {
|
||||
if len(route) == 0 {
|
||||
if nd.item != nil {
|
||||
return ErrDupItem
|
||||
return errDupItem
|
||||
}
|
||||
|
||||
nd.item = item
|
||||
@ -149,7 +160,7 @@ func add(nd *node, route string, item interface{}) error {
|
||||
}
|
||||
|
||||
if route[0] == slash {
|
||||
return ErrDupSlash
|
||||
return errDupSlash
|
||||
}
|
||||
|
||||
for i := range route {
|
||||
@ -161,7 +172,7 @@ func add(nd *node, route string, item interface{}) error {
|
||||
return add(child, route[i+1:], item)
|
||||
}
|
||||
|
||||
return ErrInvalidState
|
||||
return errInvalidState
|
||||
}
|
||||
|
||||
child := newNode(nil)
|
||||
@ -173,7 +184,7 @@ func add(nd *node, route string, item interface{}) error {
|
||||
children := nd.getChildren(route)
|
||||
if child, ok := children[route]; ok {
|
||||
if child.item != nil {
|
||||
return ErrDupItem
|
||||
return errDupItem
|
||||
}
|
||||
|
||||
child.item = item
|
||||
@ -192,6 +203,14 @@ func addParam(result *Result, k, v string) {
|
||||
result.Params[k] = v
|
||||
}
|
||||
|
||||
func duplicatedItem(item string) error {
|
||||
return fmt.Errorf("duplicated item for %s", item)
|
||||
}
|
||||
|
||||
func duplicatedSlash(item string) error {
|
||||
return fmt.Errorf("duplicated slash for %s", item)
|
||||
}
|
||||
|
||||
func match(pat, token string) innerResult {
|
||||
if pat[0] == colon {
|
||||
return innerResult{
|
||||
|
@ -151,9 +151,9 @@ func TestAddDuplicate(t *testing.T) {
|
||||
err := tree.Add("/a/b", 1)
|
||||
assert.Nil(t, err)
|
||||
err = tree.Add("/a/b", 2)
|
||||
assert.Equal(t, ErrDupItem, err)
|
||||
assert.Error(t, errDupItem, err)
|
||||
err = tree.Add("/a/b/", 2)
|
||||
assert.Equal(t, ErrDupItem, err)
|
||||
assert.Error(t, errDupItem, err)
|
||||
}
|
||||
|
||||
func TestPlain(t *testing.T) {
|
||||
@ -169,19 +169,19 @@ func TestPlain(t *testing.T) {
|
||||
func TestSearchWithDoubleSlashes(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("//a", 1)
|
||||
assert.Error(t, ErrDupSlash, err)
|
||||
assert.Error(t, errDupSlash, err)
|
||||
}
|
||||
|
||||
func TestSearchInvalidRoute(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("", 1)
|
||||
assert.Equal(t, ErrNotFromRoot, err)
|
||||
assert.Equal(t, errNotFromRoot, err)
|
||||
err = tree.Add("bad", 1)
|
||||
assert.Equal(t, ErrNotFromRoot, err)
|
||||
assert.Equal(t, errNotFromRoot, err)
|
||||
}
|
||||
|
||||
func TestSearchInvalidItem(t *testing.T) {
|
||||
tree := NewTree()
|
||||
err := tree.Add("/", nil)
|
||||
assert.Equal(t, ErrEmptyItem, err)
|
||||
assert.Equal(t, errEmptyItem, err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user