GoDoxy/internal/utils/trie/key.go
2025-04-24 05:56:03 +08:00

80 lines
1.4 KiB
Go

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
}