package codec import ( ctxpkg "github.com/noahlann/nnet/pkg/context" protocolpkg "github.com/noahlann/nnet/pkg/protocol" ) // Resolver Codec解析器接口 // 每个Resolver负责一种Codec选择策略,支持双向解析(解码和编码) type Resolver interface { // ResolveForDecode 解析用于解码的Codec(数据流入) // registry: 编解码器注册表(可以动态注册codec) // ctx: 请求上下文 // raw: 原始数据 // header: 协议帧头(如果有) // 返回: 解析到的Codec,如果无法解析返回nil和nil错误(继续下一个resolver) // 注意:resolver可以将解析到的codec注册到registry中,供后续使用 ResolveForDecode(registry Registry, ctx ctxpkg.Context, raw []byte, header protocolpkg.FrameHeader) (Codec, error) // ResolveForEncode 解析用于编码的Codec(数据流出) // registry: 编解码器注册表(可以动态注册codec) // ctx: 请求上下文 // data: 要编码的数据(Go对象) // header: 协议帧头(如果有) // 返回: 解析到的Codec,如果无法解析返回nil和nil错误(继续下一个resolver) // 注意:通常流入时已经将codec注册到registry,这里可以直接获取 ResolveForEncode(registry Registry, ctx ctxpkg.Context, data interface{}, header protocolpkg.FrameHeader) (Codec, error) } // ResolverChain Codec解析器链 // 按顺序尝试每个Resolver,直到找到可用的Codec type ResolverChain struct { resolvers []Resolver registry Registry defaultName string } // NewResolverChain 创建解析器链 func NewResolverChain(registry Registry, defaultName string) *ResolverChain { return &ResolverChain{ resolvers: make([]Resolver, 0), registry: registry, defaultName: defaultName, } } // Add 添加解析器到链中 func (c *ResolverChain) Add(resolver Resolver) *ResolverChain { c.resolvers = append(c.resolvers, resolver) return c } // ResolveForDecode 执行解析器链用于解码,返回第一个成功解析的Codec // 如果所有resolver都无法解析,返回默认Codec func (c *ResolverChain) ResolveForDecode(ctx ctxpkg.Context, raw []byte, header protocolpkg.FrameHeader) (Codec, error) { // 按顺序尝试每个resolver for _, resolver := range c.resolvers { codec, err := resolver.ResolveForDecode(c.registry, ctx, raw, header) if err != nil { // 如果resolver返回错误,继续下一个 continue } if codec != nil { return codec, nil } } // 所有resolver都无法解析,使用默认 if c.defaultName != "" { if codec, err := c.registry.Get(c.defaultName); err == nil { return codec, nil } } return c.registry.Default(), nil } // ResolveForEncode 执行解析器链用于编码,返回第一个成功解析的Codec // 如果所有resolver都无法解析,返回默认Codec func (c *ResolverChain) ResolveForEncode(ctx ctxpkg.Context, data interface{}, header protocolpkg.FrameHeader) (Codec, error) { // 按顺序尝试每个resolver for _, resolver := range c.resolvers { codec, err := resolver.ResolveForEncode(c.registry, ctx, data, header) if err != nil { // 如果resolver返回错误,继续下一个 continue } if codec != nil { return codec, nil } } // 所有resolver都无法解析,使用默认 if c.defaultName != "" { if codec, err := c.registry.Get(c.defaultName); err == nil { return codec, nil } } return c.registry.Default(), nil }