mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-25 10:18:59 +02:00
feat: trie implementation
This commit is contained in:
80
internal/utils/trie/key.go
Normal file
80
internal/utils/trie/key.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package trie
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||
)
|
||||
|
||||
type Key struct {
|
||||
segments []string // escaped segments
|
||||
full string // unescaped original key
|
||||
hasWildcard bool
|
||||
}
|
||||
|
||||
func Namespace(ns string) *Key {
|
||||
return &Key{
|
||||
segments: []string{ns},
|
||||
full: ns,
|
||||
hasWildcard: false,
|
||||
}
|
||||
}
|
||||
|
||||
func NewKey(keyStr string) *Key {
|
||||
key := &Key{
|
||||
segments: strutils.SplitRune(keyStr, '.'),
|
||||
full: keyStr,
|
||||
}
|
||||
for _, seg := range key.segments {
|
||||
if seg == "*" || seg == "**" {
|
||||
key.hasWildcard = true
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func EscapeSegment(seg string) string {
|
||||
var sb strings.Builder
|
||||
for _, r := range seg {
|
||||
switch r {
|
||||
case '.', '*':
|
||||
sb.WriteString("__")
|
||||
default:
|
||||
sb.WriteRune(r)
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (ns Key) With(segment string) *Key {
|
||||
ns.segments = append(ns.segments, segment)
|
||||
ns.full = ns.full + "." + segment
|
||||
ns.hasWildcard = ns.hasWildcard || segment == "*" || segment == "**"
|
||||
return &ns
|
||||
}
|
||||
|
||||
func (ns Key) WithEscaped(segment string) *Key {
|
||||
ns.segments = append(ns.segments, EscapeSegment(segment))
|
||||
ns.full = ns.full + "." + segment
|
||||
return &ns
|
||||
}
|
||||
|
||||
func (ns *Key) NumSegments() int {
|
||||
return len(ns.segments)
|
||||
}
|
||||
|
||||
func (ns *Key) HasWildcard() bool {
|
||||
return ns.hasWildcard
|
||||
}
|
||||
|
||||
func (ns *Key) String() string {
|
||||
return ns.full
|
||||
}
|
||||
|
||||
func (ns *Key) Clone() *Key {
|
||||
clone := *ns
|
||||
clone.segments = slices.Clone(ns.segments)
|
||||
clone.full = strings.Clone(ns.full)
|
||||
return &clone
|
||||
}
|
||||
Reference in New Issue
Block a user