1 Star 0 Fork 0

carlmax_my/console-core-go

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
urltable.go 3.44 KB
一键复制 编辑 原始数据 按行查看 历史
carlmax_my 提交于 2024-12-02 21:32 . init project
package urltable
import (
"net/http"
"strings"
"gitee.com/carlmax_my/console-core-go/pkg/errors"
)
const (
empty = ""
fuzzy = "*"
omitted = "**"
delimiter = "/"
methodView = "VIEW"
)
// parse and validate pattern
func parse(pattern string) ([]string, error) {
const format = "[get, post, put, patch, delete, view]/{a-Z}+/{*}+/{**}"
if pattern = strings.TrimLeft(strings.TrimSpace(pattern), delimiter); pattern == "" {
return nil, errors.Errorf("pattern illegal, should in format of %s", format)
}
paths := strings.Split(pattern, delimiter)
if len(paths) < 2 {
return nil, errors.Errorf("pattern illegal, should in format of %s", format)
}
for i := range paths {
paths[i] = strings.TrimSpace(paths[i])
}
// likes get/ get/* get/**
if len(paths) == 2 && (paths[1] == empty || paths[1] == fuzzy || paths[1] == omitted) {
return nil, errors.New("illegal wildcard")
}
switch paths[0] = strings.ToUpper(paths[0]); paths[0] {
case http.MethodGet,
http.MethodPost,
http.MethodPut,
http.MethodPatch,
http.MethodDelete,
methodView:
default:
return nil, errors.Errorf("only supports [%s %s %s %s %s %s]",
http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete, methodView)
}
for k := 1; k < len(paths); k++ {
if paths[k] == empty && k+1 != len(paths) {
return nil, errors.New("pattern contains illegal empty path")
}
if paths[k] == omitted && k+1 != len(paths) {
return nil, errors.New("pattern contains illegal omitted path")
}
}
return paths, nil
}
// Format pattern
func Format(pattern string) (string, error) {
paths, err := parse(pattern)
if err != nil {
return "", err
}
return strings.Join(paths, delimiter), nil
}
type section struct {
leaf bool
mapping map[string]*section
}
func newSection() *section {
return &section{mapping: make(map[string]*section)}
}
// Table a (thread unsafe) table to store urls
type Table struct {
size int
root *section
}
// NewTable create a table
func NewTable() *Table {
return &Table{root: newSection()}
}
// Size contains how many urls
func (t *Table) Size() int {
return t.size
}
// Append pattern
func (t *Table) Append(pattern string) error {
paths, err := parse(pattern)
if err != nil {
return err
}
insert := false
root := t.root
for i, path := range paths {
if (path == fuzzy && root.mapping[omitted] != nil) ||
(path == omitted && root.mapping[fuzzy] != nil) ||
(path != omitted && root.mapping[omitted] != nil) {
return errors.Errorf("conflict at %s", strings.Join(paths[:i], delimiter))
}
next := root.mapping[path]
if next == nil {
next = newSection()
root.mapping[path] = next
insert = true
}
root = next
}
if insert {
t.size++
}
root.leaf = true
return nil
}
// Mapping url to pattern
func (t *Table) Mapping(url string) (string, error) {
paths, err := parse(url)
if err != nil {
return "", err
}
pattern := make([]string, 0, len(paths))
root := t.root
for _, path := range paths {
next := root.mapping[path]
if next == nil {
nextFuzzy := root.mapping[fuzzy]
nextOmitted := root.mapping[omitted]
if nextFuzzy == nil && nextOmitted == nil {
return "", nil
}
if nextOmitted != nil {
pattern = append(pattern, omitted)
return strings.Join(pattern, delimiter), nil
}
next = nextFuzzy
path = fuzzy
}
root = next
pattern = append(pattern, path)
}
if root.leaf {
return strings.Join(pattern, delimiter), nil
}
return "", nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/carlmax_my/console-core-go.git
git@gitee.com:carlmax_my/console-core-go.git
carlmax_my
console-core-go
console-core-go
v0.0.24

搜索帮助