You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.2 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package router
import (
ctxpkg "github.com/noahlann/nnet/pkg/context"
protocolpkg "github.com/noahlann/nnet/pkg/protocol"
)
// MatchInput 匹配输入
type MatchInput struct {
// Raw 原始数据(未解码)
Raw []byte
// Header 协议帧头(如果存在)
Header protocolpkg.FrameHeader
// DataBytes 协议数据部分的原始字节协议解码后、codec解码前
DataBytes []byte
// Data 协议数据部分的解码结果codec解码后的Go对象
Data interface{}
}
// Matcher 路由匹配器接口
type Matcher interface {
// Match 根据输入和上下文执行匹配
Match(input MatchInput, ctx ctxpkg.Context) bool
// Priority 获取优先级(数字越大优先级越高)
Priority() int
}
// StringMatcher 字符串匹配器(针对原始数据)
type StringMatcher struct {
pattern string
priority int
}
// NewStringMatcher 创建字符串匹配器
func NewStringMatcher(pattern string) *StringMatcher {
return &StringMatcher{
pattern: pattern,
priority: 100, // 默认优先级
}
}
// WithPriority 设置优先级
func (m *StringMatcher) WithPriority(priority int) *StringMatcher {
m.priority = priority
return m
}
// Match 匹配字符串
func (m *StringMatcher) Match(input MatchInput, ctx ctxpkg.Context) bool {
dataBytes := input.Raw
if len(input.DataBytes) > 0 {
dataBytes = input.DataBytes
}
// 支持精确匹配和前缀匹配
dataStr := string(dataBytes)
if dataStr == m.pattern {
return true
}
// 支持通配符匹配(简单实现)
if len(m.pattern) > 0 && m.pattern[len(m.pattern)-1] == '*' {
prefix := m.pattern[:len(m.pattern)-1]
if len(dataStr) >= len(prefix) && dataStr[:len(prefix)] == prefix {
return true
}
}
return false
}
// Priority 获取优先级
func (m *StringMatcher) Priority() int {
return m.priority
}
// Pattern 获取匹配模式
func (m *StringMatcher) Pattern() string {
return m.pattern
}
// CompositeMatcher 组合匹配器(支持 AND / OR
type CompositeMatcher struct {
matchers []Matcher
mode string // "and" or "or"
priority int
}
// NewAndMatcher 创建 AND 组合匹配器(全部子匹配器需匹配)
func NewAndMatcher(matchers ...Matcher) *CompositeMatcher {
return &CompositeMatcher{
matchers: matchers,
mode: "and",
priority: 100, // 默认优先级
}
}
// NewOrMatcher 创建 OR 组合匹配器(任一子匹配器匹配即可)
func NewOrMatcher(matchers ...Matcher) *CompositeMatcher {
return &CompositeMatcher{
matchers: matchers,
mode: "or",
priority: 100, // 默认优先级
}
}
// WithPriority 设置优先级
func (m *CompositeMatcher) WithPriority(priority int) *CompositeMatcher {
m.priority = priority
return m
}
// Match 组合匹配
func (m *CompositeMatcher) Match(input MatchInput, ctx ctxpkg.Context) bool {
if len(m.matchers) == 0 {
return false
}
switch m.mode {
case "and":
for _, child := range m.matchers {
if child == nil || !child.Match(input, ctx) {
return false
}
}
return true
case "or":
for _, child := range m.matchers {
if child != nil && child.Match(input, ctx) {
return true
}
}
return false
default:
return false
}
}
// Priority 获取优先级
func (m *CompositeMatcher) Priority() int {
return m.priority
}