package router import ( "sort" "sync" "github.com/noahlann/nnet/internal/router/matcher" ctxpkg "github.com/noahlann/nnet/pkg/context" "github.com/noahlann/nnet/pkg/errors" "github.com/noahlann/nnet/pkg/router" ) // routerImpl 路由器实现 type routerImpl struct { routes []*route mu sync.RWMutex } // NewRouter 创建新路由器 func NewRouter() router.Router { return &routerImpl{ routes: make([]*route, 0), } } // Register 注册路由 func (r *routerImpl) Register(matcher router.Matcher, handler router.Handler, opts ...router.RouteOption) router.Route { r.mu.Lock() defer r.mu.Unlock() // 应用路由选项 config := &router.RouteConfig{} for _, opt := range opts { opt(config) } rt := newRoute(matcher, handler, config) r.routes = append(r.routes, rt) // 按优先级排序(优先级高的在前) sort.Slice(r.routes, func(i, j int) bool { return r.routes[i].matcher.Priority() > r.routes[j].matcher.Priority() }) return rt } // RegisterString 注册字符串路由 func (r *routerImpl) RegisterString(pattern string, handler router.Handler, opts ...router.RouteOption) router.Route { matcher := router.NewStringMatcher(pattern) return r.Register(matcher, handler, opts...) } // RegisterFrameHeader 注册帧头匹配路由 func (r *routerImpl) RegisterFrameHeader(field, operator string, value interface{}, handler router.Handler, opts ...router.RouteOption) router.Route { m := matcher.NewFrameHeaderMatcher(field, operator, value) return r.Register(m, handler, opts...) } // RegisterFrameData 注册帧数据匹配路由 func (r *routerImpl) RegisterFrameData(path, operator string, value interface{}, handler router.Handler, opts ...router.RouteOption) router.Route { m := matcher.NewFrameDataMatcher(path, operator, value) return r.Register(m, handler, opts...) } // RegisterCustom 注册自定义匹配路由 func (r *routerImpl) RegisterCustom(fn func(input router.MatchInput, ctx ctxpkg.Context) bool, handler router.Handler, opts ...router.RouteOption) router.Route { m := router.NewCustomMatcher(fn) return r.Register(m, handler, opts...) } // Group 创建路由分组 func (r *routerImpl) Group() router.RouterGroup { return newRouterGroup(r, "") } // Match 匹配路由 func (r *routerImpl) Match(input router.MatchInput, ctx ctxpkg.Context) (router.Route, router.Handler, error) { r.mu.RLock() defer r.mu.RUnlock() // 按优先级顺序匹配 for _, route := range r.routes { if route.matcher.Match(input, ctx) { return route, route.Handler(), nil } } return nil, nil, errors.ErrRouteNotFound }