Documentation
¶
Overview ¶
Package pbmo 在 protobuf 生成结构体与领域/GORM 模型之间做字段映射转换
本包不参与 protobuf 线格式编解码:不调用 proto.Marshal/Unmarshal/Clone, 也不走 protojson对 google.golang.org/protobuf 的依赖仅用于 WKT 类型 (timestamppb / wrapperspb / structpb)与一次 proto.Message 接口判定
性能模型 ¶
转换计划按 reflect.Type 编译一次后缓存,热路径只做一次原子读 + 一次闭包调用, 稳态零反射字段按偏移合并为连续 memmove 段,WKT 子对象的多次分配被合并为 单次复合分配——因此 Model→PB 的 wrapper 路径可以比手写代码更快(分配更少)
字段别名语义(重要) ¶
为保持热路径零拷贝,标量与切片类字段**不做防御性复制**:
- 标量、定长数组:按值 memmove 到目标,相互独立
- []byte 与其他切片字段:**只拷贝切片头(指针 + 长度 + 容量)**, 源与目标因此共享同一底层数组修改 src[0] 会改变 dst[0],反之亦然
- map 字段:拷贝 map 头,源与目标指向同一个 map
- 指针字段:拷贝指针值,源与目标指向同一对象
这是有意的设计(跨节点扇出等场景据此省掉整份载荷复制),但调用方必须知道: 若转换后仍会改写源对象,且目标的生命周期更长,则需要自行深拷贝相关字段
PBToUpdates / ModelToUpdates 输出的 map 值是**值快照**(标量经值拷贝后装箱), 不随源结构体后续改动而变化;但指针类字段的值仍是共享指针
目标归属与 Into 变体 ¶
ToPB / FromPB 必须为结果分配目标并返回,该分配必然逃逸,是这两条路径 100% 的垃圾来源与并行扩展的实际天花板需要稳态零分配时改用 ToPBInto / FromPBInto 写入调用方持有的目标,但要遵守其文档中的清零契约: 拷贝计划只写有映射关系的字段,复用脏目标会残留上一轮的值
Index ¶
- Constants
- Variables
- func BoolValueToPtr(v *wrapperspb.BoolValue) *bool
- func ConvertEnum[S, T any](mapper *EnumMapper, source S, defaultValue T) T
- func DerefBoolVal(v *wrapperspb.BoolValue) bool
- func DerefDoubleVal(v *wrapperspb.DoubleValue) float64
- func DerefFloatVal(v *wrapperspb.FloatValue) float32
- func DerefInt32Val(v *wrapperspb.Int32Value) int32
- func DerefInt64Val(v *wrapperspb.Int64Value) int64
- func DerefSlice[T any](ptrs []*T) []T
- func DerefStringVal(v *wrapperspb.StringValue) string
- func DerefUInt32Val(v *wrapperspb.UInt32Value) uint32
- func DerefUInt64Val(v *wrapperspb.UInt64Value) uint64
- func DereferenceType(t reflect.Type) reflect.Type
- func DoubleValueToPtr(v *wrapperspb.DoubleValue) *float64
- func FloatValueToPtr(v *wrapperspb.FloatValue) *float32
- func FromPB[P any, M any](pb *P) (*M, error)
- func FromPBInto[P any, M any](pb *P, dst *M) error
- func FromPBs[P any, M any](pbs []*P) ([]*M, error)
- func GetTypeName(t reflect.Type) string
- func Int32ValueToPtr(v *wrapperspb.Int32Value) *int32
- func Int64ValueToPtr(v *wrapperspb.Int64Value) *int64
- func IsConversionError(err error) bool
- func IsIntegerType(t reflect.Type) bool
- func IsNilValueError(err error) bool
- func IsSignedInt(kind reflect.Kind) bool
- func IsStructPtrType(t reflect.Type) bool
- func IsTimeType(t reflect.Type) bool
- func IsTimestampPtrType(t reflect.Type) bool
- func IsTypeMismatchError(err error) bool
- func IsUnsignedInt(kind reflect.Kind) bool
- func IsValidationError(err error) bool
- func ModelToUpdates[M any](m *M) map[string]interface{}
- func NewBatchError(format string, args ...interface{}) error
- func NewConversionError(format string, args ...interface{}) error
- func NewDesensitizeError(format string, args ...interface{}) error
- func NewFieldMappingError(format string, args ...interface{}) error
- func NewNilValueError(format string, args ...interface{}) error
- func NewTypeMismatchError(format string, args ...interface{}) error
- func NewValidationError(format string, args ...interface{}) error
- func PBToUpdates[P any](pb *P) map[string]interface{}
- func ProtoTimestampToTime(ts *timestamppb.Timestamp) time.Time
- func ProtoTimestampToTimePointer(ts *timestamppb.Timestamp) *time.Time
- func PtrToBoolValue(v *bool) *wrapperspb.BoolValue
- func PtrToDoubleValue(v *float64) *wrapperspb.DoubleValue
- func PtrToFloatValue(v *float32) *wrapperspb.FloatValue
- func PtrToInt32Value(v *int32) *wrapperspb.Int32Value
- func PtrToInt64Value(v *int64) *wrapperspb.Int64Value
- func PtrToStringValue(v *string) *wrapperspb.StringValue
- func PtrToUInt32Value(v *uint32) *wrapperspb.UInt32Value
- func PtrToUInt64Value(v *uint64) *wrapperspb.UInt64Value
- func StringValueToPtr(v *wrapperspb.StringValue) *string
- func TimePointerToProtoTimestamp(t *time.Time) *timestamppb.Timestamp
- func TimeToProtoTimestamp(t time.Time) *timestamppb.Timestamp
- func ToPB[M any, P any](m *M) (*P, error)
- func ToPBInto[M any, P any](m *M, dst *P) error
- func ToPBs[M any, P any](models []*M) ([]*P, error)
- func UInt32ValueToPtr(v *wrapperspb.UInt32Value) *uint32
- func UInt64ValueToPtr(v *wrapperspb.UInt64Value) *uint64
- type AutoEnumConverter
- func (ac *AutoEnumConverter[S, T]) AutoRegister(mappings map[S]T) *AutoEnumConverter[S, T]
- func (ac *AutoEnumConverter[S, T]) Convert(source S) T
- func (ac *AutoEnumConverter[S, T]) ConvertBack(target T) (S, bool)
- func (ac *AutoEnumConverter[S, T]) ConvertSlice(sources []S) []T
- func (ac *AutoEnumConverter[S, T]) ConvertWithDefault(source S, defaultValue T) T
- type BatchItem
- type BatchResult
- type BidiConverter
- func (bc *BidiConverter) ConvertModelToPB(model, pbPtr interface{}) error
- func (bc *BidiConverter) ConvertPBToModel(pb, modelPtr interface{}) error
- func (bc *BidiConverter) GetModelType() reflect.Type
- func (bc *BidiConverter) GetPBType() reflect.Type
- func (bc *BidiConverter) GetTransformers() *TransformerRegistry
- func (bc *BidiConverter) RegisterFieldMapping(mappings map[string]string) *BidiConverter
- func (bc *BidiConverter) RegisterTransformer(field string, fn TransformerFunc) *BidiConverter
- func (bc *BidiConverter) Warmup() *BidiConverter
- func (bc *BidiConverter) WithAutoTimeConversion(enabled bool) *BidiConverter
- func (bc *BidiConverter) WithBatchSize(size int) *BidiConverter
- func (bc *BidiConverter) WithConcurrency(n int) *BidiConverter
- func (bc *BidiConverter) WithDesensitize(enabled bool) *BidiConverter
- func (bc *BidiConverter) WithFieldMapping(modelField, pbField string) *BidiConverter
- func (bc *BidiConverter) WithFieldMappings(mappings map[string]string) *BidiConverter
- func (bc *BidiConverter) WithSafeMode(enabled bool) *BidiConverter
- func (bc *BidiConverter) WithTagMapping(enabled bool) *BidiConverter
- func (bc *BidiConverter) WithTagName(name string) *BidiConverter
- func (bc *BidiConverter) WithTimeout(timeout time.Duration) *BidiConverter
- type Converter
- type EnumMapper
- func (em *EnumMapper) AddMapping(source, target int32) *EnumMapper
- func (em *EnumMapper) AddMappings(pairs [][2]int32) *EnumMapper
- func (em *EnumMapper) Map(source int32, defaultValue int32) int32
- func (em *EnumMapper) MapEnum(sourceEnum interface{}, targetEnumType reflect.Type, defaultValue interface{}) (interface{}, error)
- func (em *EnumMapper) ReverseMap(target int32, defaultValue int32) int32
- type Error
- type ErrorType
- type GenericEnumMapper
- func (m *GenericEnumMapper[S, T]) Map(source S) T
- func (m *GenericEnumMapper[S, T]) MapSlice(sources []S) []T
- func (m *GenericEnumMapper[S, T]) MapWithDefault(source S, defaultValue T) T
- func (m *GenericEnumMapper[S, T]) Register(source S, target T) *GenericEnumMapper[S, T]
- func (m *GenericEnumMapper[S, T]) RegisterBatch(pairs map[S]T) *GenericEnumMapper[S, T]
- func (m *GenericEnumMapper[S, T]) ReverseMap(target T) (S, bool)
- type IntWrapper
- type Option
- func WithAutoTimeConversion(enabled bool) Option
- func WithBatchSize(size int) Option
- func WithConcurrency(n int) Option
- func WithDesensitize(enabled bool) Option
- func WithFieldMapping(modelField, pbField string) Option
- func WithFieldMappings(mappings map[string]string) Option
- func WithSafeMode(enabled bool) Option
- func WithTagMapping(enabled bool) Option
- func WithTagName(name string) Option
- func WithTimeout(timeout time.Duration) Option
- type Options
- type Registry
- func (r *Registry) Clear()
- func (r *Registry) ConvertModelToPB(model, pb interface{}) error
- func (r *Registry) ConvertPBToModel(pb, model interface{}) error
- func (r *Registry) Count() int
- func (r *Registry) Has(pbType, modelType reflect.Type) bool
- func (r *Registry) Keys() []string
- func (r *Registry) Lookup(pbType, modelType reflect.Type) (*BidiConverter, error)
- func (r *Registry) LookupByInstance(pb, model interface{}) (*BidiConverter, error)
- func (r *Registry) MustLookup(pbType, modelType reflect.Type) *BidiConverter
- func (r *Registry) MustRegister(converter *BidiConverter)
- func (r *Registry) Register(converter *BidiConverter) error
- func (r *Registry) Unregister(pbType, modelType reflect.Type)
- type SafeConverter
- type TestAllSlowInnerModel
- type TestAllSlowInnerPB
- type TestAllTypesModel
- type TestAllTypesPB
- type TestDataWrapperModel
- type TestDataWrapperPB
- type TestEmptyModel
- type TestEmptyPB
- type TestInnerModel
- type TestInnerPB
- type TestMapModel
- type TestMapPB
- type TestMapStringSliceModel
- type TestMapStringSlicePB
- type TestMapStructModel
- type TestMapStructPB
- type TestMixedInnerModel
- type TestMixedInnerPB
- type TestModel
- type TestModelAllTypes
- type TestModelForUpdates
- type TestModelJsonTag
- type TestModelNoPbmoTag
- type TestModelUnexported
- type TestModelWithMapping
- type TestNamedSliceModel
- type TestNamedSlicePB
- type TestNestModel
- type TestNestPB
- type TestNestedAutoModel
- type TestNestedAutoPB
- type TestOuterAllSlowModel
- type TestOuterAllSlowPB
- type TestOuterMixedModel
- type TestOuterMixedPB
- type TestOuterValueStructModel
- type TestOuterValueStructPB
- type TestPB
- type TestPBNoPbmoTag
- type TestPBUpdatesEmpty
- type TestPBUpdatesMsg
- type TestPBUpdatesNoTag
- type TestPBWithMapping
- type TestSimpleModel
- type TestSimplePB
- type TestSingleFieldModel
- type TestSingleFieldPB
- type TestSliceStructModel
- type TestSliceStructPB
- type TestSliceValueStructModel
- type TestSliceValueStructPB
- type TestStringSlice
- type TestTimePtrModel
- type TestTimePtrPB
- type TestTimeZeroModel
- type TestTimeZeroPB
- type TestWrapperFieldModel
- type TestWrapperFieldPB
- type TestWrapperValueModel
- type TestWrapperValuePB
- type TransformerFunc
- type TransformerRegistry
- func (tr *TransformerRegistry) Apply(field string, value reflect.Value) reflect.Value
- func (tr *TransformerRegistry) Clear()
- func (tr *TransformerRegistry) Clone() *TransformerRegistry
- func (tr *TransformerRegistry) Count() int
- func (tr *TransformerRegistry) Fields() []string
- func (tr *TransformerRegistry) Has(field string) bool
- func (tr *TransformerRegistry) Lookup(field string) (TransformerFunc, bool)
- func (tr *TransformerRegistry) Register(field string, fn TransformerFunc)
- func (tr *TransformerRegistry) RegisterBatch(transformers map[string]TransformerFunc)
- func (tr *TransformerRegistry) Remove(field string)
- type UpdatesBuilder
- func (b *UpdatesBuilder) Build() map[string]interface{}
- func (b *UpdatesBuilder) Clear() *UpdatesBuilder
- func (b *UpdatesBuilder) Delete(key string) *UpdatesBuilder
- func (b *UpdatesBuilder) Has(key string) bool
- func (b *UpdatesBuilder) IsEmpty() bool
- func (b *UpdatesBuilder) Len() int
- func (b *UpdatesBuilder) Merge(other *UpdatesBuilder) *UpdatesBuilder
- func (b *UpdatesBuilder) Set(key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetBoolVal(key string, val *wrapperspb.BoolValue) *UpdatesBuilder
- func (b *UpdatesBuilder) SetDoubleVal(key string, val *wrapperspb.DoubleValue) *UpdatesBuilder
- func (b *UpdatesBuilder) SetFloatVal(key string, val *wrapperspb.FloatValue) *UpdatesBuilder
- func (b *UpdatesBuilder) SetIf(condition bool, key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetIfNotEmpty(key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetIfNotNil(key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetIfNotZero(key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetInt32Val(key string, val *wrapperspb.Int32Value) *UpdatesBuilder
- func (b *UpdatesBuilder) SetInt64Val(key string, val *wrapperspb.Int64Value) *UpdatesBuilder
- func (b *UpdatesBuilder) SetJSON(key string, value string, defaultJSON ...string) *UpdatesBuilder
- func (b *UpdatesBuilder) SetJSONSlice(key string, value interface{}) *UpdatesBuilder
- func (b *UpdatesBuilder) SetJSONVal(key string, val *wrapperspb.StringValue, defaultJSON ...string) *UpdatesBuilder
- func (b *UpdatesBuilder) SetNull(key string) *UpdatesBuilder
- func (b *UpdatesBuilder) SetString(key string, val string) *UpdatesBuilder
- func (b *UpdatesBuilder) SetStringVal(key string, val *wrapperspb.StringValue) *UpdatesBuilder
- func (b *UpdatesBuilder) SetStringValAny(key string, val *wrapperspb.StringValue) *UpdatesBuilder
- func (b *UpdatesBuilder) SetStringValOrEmpty(key string, val *wrapperspb.StringValue) *UpdatesBuilder
- func (b *UpdatesBuilder) String() string
Constants ¶
PtrSize 是 unsafe.Sizeof(unsafe.Pointer(nil)) 的常量,用于指针算术
Variables ¶
var ( ErrPBMessageNil = Error{Msg: "PB消息不能为空", Type: ErrTypeNilValue} ErrModelNil = Error{Msg: "Model不能为空", Type: ErrTypeNilValue} ErrMustBePointer = Error{Msg: "目标必须是指针类型", Type: ErrTypeTypeMismatch} ErrMustBeSlice = Error{Msg: "源必须是切片类型", Type: ErrTypeTypeMismatch} ErrMustBeStruct = Error{Msg: "目标必须是结构体类型", Type: ErrTypeTypeMismatch} ErrConverterExists = Error{Msg: "转换器已存在", Type: ErrTypeRegistry} ErrConverterNotFound = Error{Msg: "转换器未找到", Type: ErrTypeRegistry} )
Functions ¶
func BoolValueToPtr ¶
func BoolValueToPtr(v *wrapperspb.BoolValue) *bool
BoolValueToPtr 将 *wrapperspb.BoolValue 转换为 *bool 当源值为 nil 指针时,BoolValueToPtr 返回 nil 指针
func ConvertEnum ¶
func ConvertEnum[S, T any](mapper *EnumMapper, source S, defaultValue T) T
ConvertEnum 便捷方法:转换枚举(自动推断类型)
func DerefBoolVal ¶
func DerefBoolVal(v *wrapperspb.BoolValue) bool
DerefBoolVal 从 *wrapperspb.BoolValue 中提取布尔值 当源值为 nil 指针时,DerefBoolVal 返回 false
func DerefDoubleVal ¶
func DerefDoubleVal(v *wrapperspb.DoubleValue) float64
DerefDoubleVal 从 *wrapperspb.DoubleValue 中提取浮点数值 当源值为 nil 指针时,DerefDoubleVal 返回 0.0
func DerefFloatVal ¶
func DerefFloatVal(v *wrapperspb.FloatValue) float32
DerefFloatVal 从 *wrapperspb.FloatValue 中提取浮点数值 当源值为 nil 指针时,DerefFloatVal 返回 0.0
func DerefInt32Val ¶
func DerefInt32Val(v *wrapperspb.Int32Value) int32
DerefInt32Val 从 *wrapperspb.Int32Value 中提取整数值 当源值为 nil 指针时,DerefInt32Val 返回 0
func DerefInt64Val ¶
func DerefInt64Val(v *wrapperspb.Int64Value) int64
DerefInt64Val 从 *wrapperspb.Int64Value 中提取整数值 当源值为 nil 指针时,DerefInt64Val 返回 0
func DerefStringVal ¶
func DerefStringVal(v *wrapperspb.StringValue) string
DerefStringVal 从 *wrapperspb.StringValue 中提取字符串值 当源值为 nil 指针时,DerefStringVal 返回空字符串 ""
func DerefUInt32Val ¶
func DerefUInt32Val(v *wrapperspb.UInt32Value) uint32
DerefUInt32Val 从 *wrapperspb.UInt32Value 中提取无符号整数值 当源值为 nil 指针时,DerefUInt32Val 返回 0
func DerefUInt64Val ¶
func DerefUInt64Val(v *wrapperspb.UInt64Value) uint64
DerefUInt64Val 从 *wrapperspb.UInt64Value 中提取无符号整数值 当源值为 nil 指针时,DerefUInt64Val 返回 0
func DereferenceType ¶
DereferenceType 解引用指针类型,返回实际类型
func DoubleValueToPtr ¶
func DoubleValueToPtr(v *wrapperspb.DoubleValue) *float64
DoubleValueToPtr 将 *wrapperspb.DoubleValue 转换为 *float64 当源值为 nil 指针时,DoubleValueToPtr 返回 nil 指针
func FloatValueToPtr ¶
func FloatValueToPtr(v *wrapperspb.FloatValue) *float32
FloatValueToPtr 将 *wrapperspb.FloatValue 转换为 *float32 当源值为 nil 指针时,FloatValueToPtr 返回 nil 指针
func FromPB ¶
FromPB 将 PB 消息转换为 Model,nil 输入返回 nil 类型字静态提取一次原子读命中即分发,纯拷贝直达合并闭包,稳态零反射
目标由本函数分配并返回,该分配必然逃逸;需要稳态零分配时改用 FromPBInto 切片/map/指针类字段与源共享底层数据,不做防御性复制(见包文档「字段别名语义」)
func FromPBInto ¶
FromPBInto 将 PB 消息转换到调用方提供的 Model 目标,免去 FromPB 的目标堆分配
与 ToPBInto 对偶,动机、契约与别名语义同上:dst 清零责任在调用方, 未映射字段保持原值;pb 为 nil 时不触碰 dst 并返回 nil;dst 为 nil 返回 ErrModelNil
func Int32ValueToPtr ¶
func Int32ValueToPtr(v *wrapperspb.Int32Value) *int32
Int32ValueToPtr 将 *wrapperspb.Int32Value 转换为 *int32 当源值为 nil 指针时,Int32ValueToPtr 返回 nil 指针
func Int64ValueToPtr ¶
func Int64ValueToPtr(v *wrapperspb.Int64Value) *int64
Int64ValueToPtr 将 *wrapperspb.Int64Value 转换为 *int64 当源值为 nil 指针时,Int64ValueToPtr 返回 nil 指针
func IsIntegerType ¶
IsIntegerType 判断是否为整数类型 对应 go-toolbox/types.Integer + types.Unsigned
func IsSignedInt ¶
IsSignedInt 判断是否为有符号整数 对应 go-toolbox/types.Integer 约束
func IsStructPtrType ¶
IsStructPtrType 判断是否为 *structpb.Struct 类型
func IsTimestampPtrType ¶
IsTimestampPtrType 判断是否为 *timestamppb.Timestamp 类型
func IsTypeMismatchError ¶
IsTypeMismatchError 判断是否为类型不匹配错误
func IsUnsignedInt ¶
IsUnsignedInt 判断是否为无符号整数 对应 go-toolbox/types.Unsigned 约束
func ModelToUpdates ¶
ModelToUpdates 将 Model 结构体转换为 map[string]interface{} 使用 gorm column tag 或 json tag 作为 key,跳过零值字段和不可导出字段 字段 key 与偏移按类型缓存于更新计划,热路径零 tag 解析
func NewBatchError ¶
NewBatchError 创建批量操作错误
func NewConversionError ¶
NewConversionError 创建转换错误
func NewDesensitizeError ¶
NewDesensitizeError 创建脱敏错误
func NewFieldMappingError ¶
NewFieldMappingError 创建字段映射错误
func NewNilValueError ¶
NewNilValueError 创建空值错误
func NewTypeMismatchError ¶
NewTypeMismatchError 创建类型不匹配错误
func NewValidationError ¶
NewValidationError 创建校验错误
func PBToUpdates ¶
PBToUpdates 将 PB 消息转换为 map[string]interface{} 遍历 proto 字段,使用 protobuf json tag 名作为 key(snake_case) 自动跳过零值、protobuf 内部字段,自动解包 wrapper 类型 字段 key 与偏移按类型缓存于更新计划,热路径零 tag 解析
func ProtoTimestampToTime ¶
func ProtoTimestampToTime(ts *timestamppb.Timestamp) time.Time
ProtoTimestampToTime 将 *timestamppb.Timestamp 转换为 time.Time 如果输入为 nil,返回零值时间
func ProtoTimestampToTimePointer ¶
func ProtoTimestampToTimePointer(ts *timestamppb.Timestamp) *time.Time
ProtoTimestampToTimePointer 将 *timestamppb.Timestamp 转换为 *time.Time 如果输入为 nil,返回 nil
func PtrToBoolValue ¶
func PtrToBoolValue(v *bool) *wrapperspb.BoolValue
PtrToBoolValue 将 *bool 转换为 *wrapperspb.BoolValue 当源值为 nil 指针时,PtrToBoolValue 返回 nil 指针
func PtrToDoubleValue ¶
func PtrToDoubleValue(v *float64) *wrapperspb.DoubleValue
PtrToDoubleValue 将 *float64 转换为 *wrapperspb.DoubleValue 当源值为 nil 指针时,PtrToDoubleValue 返回 nil 指针
func PtrToFloatValue ¶
func PtrToFloatValue(v *float32) *wrapperspb.FloatValue
PtrToFloatValue 将 *float32 转换为 *wrapperspb.FloatValue 当源值为 nil 指针时,PtrToFloatValue 返回 nil 指针
func PtrToInt32Value ¶
func PtrToInt32Value(v *int32) *wrapperspb.Int32Value
PtrToInt32Value 将 *int32 转换为 *wrapperspb.Int32Value 当源值为 nil 指针时,PtrToInt32Value 返回 nil 指针
func PtrToInt64Value ¶
func PtrToInt64Value(v *int64) *wrapperspb.Int64Value
PtrToInt64Value 将 *int64 转换为 *wrapperspb.Int64Value 当源值为 nil 指针时,PtrToInt64Value 返回 nil 指针
func PtrToStringValue ¶
func PtrToStringValue(v *string) *wrapperspb.StringValue
PtrToStringValue 将 *string 转换为 *wrapperspb.StringValue 当源值为 nil 指针时,PtrToStringValue 返回 nil 指针
func PtrToUInt32Value ¶
func PtrToUInt32Value(v *uint32) *wrapperspb.UInt32Value
PtrToUInt32Value 将 *uint32 转换为 *wrapperspb.UInt32Value 当源值为 nil 指针时,PtrToUInt32Value 返回 nil 指针
func PtrToUInt64Value ¶
func PtrToUInt64Value(v *uint64) *wrapperspb.UInt64Value
PtrToUInt64Value 将 *uint64 转换为 *wrapperspb.UInt64Value 当源值为 nil 指针时,PtrToUInt64Value 返回 nil 指针
func StringValueToPtr ¶
func StringValueToPtr(v *wrapperspb.StringValue) *string
StringValueToPtr 将 *wrapperspb.StringValue 转换为 *string 当源值为 nil 指针时,StringValueToPtr 返回 nil 指针
func TimePointerToProtoTimestamp ¶
func TimePointerToProtoTimestamp(t *time.Time) *timestamppb.Timestamp
TimePointerToProtoTimestamp 将 *time.Time 转换为 *timestamppb.Timestamp 如果输入为 nil 或零值时间,返回 nil
func TimeToProtoTimestamp ¶
func TimeToProtoTimestamp(t time.Time) *timestamppb.Timestamp
TimeToProtoTimestamp 将 time.Time 转换为 *timestamppb.Timestamp 如果输入为零值时间,返回 nil
func ToPB ¶
ToPB 将 Model 转换为 PB 消息,nil 输入返回 nil 类型字静态提取一次原子读命中即分发,纯拷贝直达合并闭包,稳态零反射
目标由本函数分配并返回,该分配必然逃逸;需要稳态零分配时改用 ToPBInto 切片/map/指针类字段与源共享底层数据,不做防御性复制(见包文档「字段别名语义」)
func ToPBInto ¶
ToPBInto 将 Model 转换到调用方提供的 PB 目标,免去 ToPB 的目标堆分配
与 ToPB 的唯一差异是目标归属ToPB 必须 new(P) 后返回,该返回值必然逃逸—— 它是该路径 100% 的垃圾与约 47% 的单次耗时,也是并行扩展的真实天花板 (无锁竞争,纯分配/GC 压力:同一基准关掉 GC 后 1→10 核扩展比从 1.31× 升到 2.80×) 本函数写入调用方持有的 dst,配合对象池复用即稳态零分配
⚠️ 调用方契约:dst 的清零责任在调用方 拷贝计划只写「存在映射关系的字段」,未映射字段保持 dst 原有值不变—— 复用一个脏目标会残留上一轮的数据复用前请显式置零(*dst = P{}), 或确认该类型对的全部字段均被映射覆盖
m 为 nil 时不触碰 dst 并返回 nil(与 ToPB 的 nil→nil 语义一致); dst 为 nil 返回 ErrPBMessageNil
字段别名语义与 ToPB 完全一致:标量与 []byte/切片头经合并 memmove 直拷, 切片类字段与源共享底层数组,不做防御性复制(见包文档「字段别名语义」)
func UInt32ValueToPtr ¶
func UInt32ValueToPtr(v *wrapperspb.UInt32Value) *uint32
UInt32ValueToPtr 将 *wrapperspb.UInt32Value 转换为 *uint32 当源值为 nil 指针时,UInt32ValueToPtr 返回 nil 指针
func UInt64ValueToPtr ¶
func UInt64ValueToPtr(v *wrapperspb.UInt64Value) *uint64
UInt64ValueToPtr 将 *wrapperspb.UInt64Value 转换为 *uint64 当源值为 nil 指针时,UInt64ValueToPtr 返回 nil 指针
Types ¶
type AutoEnumConverter ¶
type AutoEnumConverter[S comparable, T comparable] struct { // contains filtered or unexported fields }
AutoEnumConverter 自动枚举转换器
func NewAutoEnumConverter ¶
func NewAutoEnumConverter[S comparable, T comparable](defaultValue T) *AutoEnumConverter[S, T]
NewAutoEnumConverter 创建自动枚举转换器
func (*AutoEnumConverter[S, T]) AutoRegister ¶
func (ac *AutoEnumConverter[S, T]) AutoRegister(mappings map[S]T) *AutoEnumConverter[S, T]
AutoRegister 自动批量注册映射关系
func (*AutoEnumConverter[S, T]) Convert ¶
func (ac *AutoEnumConverter[S, T]) Convert(source S) T
Convert 自动转换
func (*AutoEnumConverter[S, T]) ConvertBack ¶
func (ac *AutoEnumConverter[S, T]) ConvertBack(target T) (S, bool)
ConvertBack 反向转换
func (*AutoEnumConverter[S, T]) ConvertSlice ¶
func (ac *AutoEnumConverter[S, T]) ConvertSlice(sources []S) []T
ConvertSlice 批量转换
func (*AutoEnumConverter[S, T]) ConvertWithDefault ¶
func (ac *AutoEnumConverter[S, T]) ConvertWithDefault(source S, defaultValue T) T
ConvertWithDefault 带默认值转换
type BatchItem ¶
type BatchItem struct {
Index int // 索引
Success bool // 是否成功
Value interface{} // 转换后的值
Error error // 错误信息
}
BatchItem 单个转换结果
type BatchResult ¶
type BatchResult struct {
SuccessCount int // 成功数量
FailureCount int // 失败数量
Results []BatchItem // 每个元素的转换结果
}
BatchResult 批量转换结果
func SafeFromPBs ¶
func SafeFromPBs[P any, M any](pbs []*P) ([]*M, *BatchResult)
SafeFromPBs 安全批量将 PB 切片转换为 Model 切片,不因单个失败而中断 接受 []*P(指针切片),nil 元素标记为失败
func SafeToPBs ¶
func SafeToPBs[M any, P any](models []M) ([]*P, *BatchResult)
SafeToPBs 安全批量将 Model 切片转换为 PB 切片,不因单个失败而中断 自动支持 []M(值切片)和 []*M(指针切片),nil 指针元素标记为失败
type BidiConverter ¶
type BidiConverter struct {
// contains filtered or unexported fields
}
BidiConverter 双向转换器
func NewBidiConverter ¶
func NewBidiConverter(pbType, modelType interface{}, opts ...Option) *BidiConverter
NewBidiConverter 创建双向转换器 FieldMapping 惰性初始化:无映射配置时不分配 map
func RegisterWith ¶
func RegisterWith[M any, P any](opts ...Option) *BidiConverter
RegisterWith[M, P] 注册 Model-PB 转换对(自定义配置)
func (*BidiConverter) ConvertModelToPB ¶
func (bc *BidiConverter) ConvertModelToPB(model, pbPtr interface{}) error
ConvertModelToPB 将 Model 转换为 PB 消息(核心热路径) 与 ConvertPBToModel 对称,方向为 Model → PB,委托给 convertWithCache
func (*BidiConverter) ConvertPBToModel ¶
func (bc *BidiConverter) ConvertPBToModel(pb, modelPtr interface{}) error
ConvertPBToModel 将 PB 消息转换为 Model(核心热路径) 入参校验后委托给 convertWithCache,三层加速策略详见 convertWithCache 注释
func (*BidiConverter) GetModelType ¶
func (bc *BidiConverter) GetModelType() reflect.Type
GetModelType 获取 Model 类型
func (*BidiConverter) GetPBType ¶
func (bc *BidiConverter) GetPBType() reflect.Type
GetPBType 获取 PB 类型
func (*BidiConverter) GetTransformers ¶
func (bc *BidiConverter) GetTransformers() *TransformerRegistry
GetTransformers 获取转换器注册表
func (*BidiConverter) RegisterFieldMapping ¶
func (bc *BidiConverter) RegisterFieldMapping(mappings map[string]string) *BidiConverter
RegisterFieldMapping 注册字段映射
func (*BidiConverter) RegisterTransformer ¶
func (bc *BidiConverter) RegisterTransformer(field string, fn TransformerFunc) *BidiConverter
RegisterTransformer 注册字段转换器
func (*BidiConverter) Warmup ¶
func (bc *BidiConverter) Warmup() *BidiConverter
Warmup 预热缓存,在注册完成后调用确保所有映射就绪
func (*BidiConverter) WithAutoTimeConversion ¶
func (bc *BidiConverter) WithAutoTimeConversion(enabled bool) *BidiConverter
WithAutoTimeConversion 设置自动时间转换
func (*BidiConverter) WithBatchSize ¶
func (bc *BidiConverter) WithBatchSize(size int) *BidiConverter
WithBatchSize 设置批处理大小
func (*BidiConverter) WithConcurrency ¶
func (bc *BidiConverter) WithConcurrency(n int) *BidiConverter
WithConcurrency 设置并发数
func (*BidiConverter) WithDesensitize ¶
func (bc *BidiConverter) WithDesensitize(enabled bool) *BidiConverter
WithDesensitize 设置是否启用脱敏,默认关闭 开关影响拷贝计划的构建结果,必须让已建好的计划失效后重建
func (*BidiConverter) WithFieldMapping ¶
func (bc *BidiConverter) WithFieldMapping(modelField, pbField string) *BidiConverter
WithFieldMapping 设置字段映射
func (*BidiConverter) WithFieldMappings ¶
func (bc *BidiConverter) WithFieldMappings(mappings map[string]string) *BidiConverter
WithFieldMappings 批量设置字段映射
func (*BidiConverter) WithSafeMode ¶
func (bc *BidiConverter) WithSafeMode(enabled bool) *BidiConverter
WithSafeMode 设置是否启用安全模式
func (*BidiConverter) WithTagMapping ¶
func (bc *BidiConverter) WithTagMapping(enabled bool) *BidiConverter
WithTagMapping 设置是否启用 struct tag 映射
func (*BidiConverter) WithTagName ¶
func (bc *BidiConverter) WithTagName(name string) *BidiConverter
WithTagName 设置 struct tag 名称
func (*BidiConverter) WithTimeout ¶
func (bc *BidiConverter) WithTimeout(timeout time.Duration) *BidiConverter
WithTimeout 设置超时时间
type Converter ¶
type Converter interface {
ConvertPBToModel(pb, modelPtr interface{}) error
ConvertModelToPB(model, pbPtr interface{}) error
GetPBType() reflect.Type
GetModelType() reflect.Type
}
Converter 双向转换器接口
type EnumMapper ¶
type EnumMapper struct {
// contains filtered or unexported fields
}
EnumMapper int32 枚举映射器(兼容旧代码)
func (*EnumMapper) AddMapping ¶
func (em *EnumMapper) AddMapping(source, target int32) *EnumMapper
AddMapping 添加映射关系(链式调用)
func (*EnumMapper) AddMappings ¶
func (em *EnumMapper) AddMappings(pairs [][2]int32) *EnumMapper
AddMappings 批量添加映射关系
func (*EnumMapper) Map ¶
func (em *EnumMapper) Map(source int32, defaultValue int32) int32
Map 映射源枚举值到目标枚举值
func (*EnumMapper) MapEnum ¶
func (em *EnumMapper) MapEnum(sourceEnum interface{}, targetEnumType reflect.Type, defaultValue interface{}) (interface{}, error)
MapEnum 通用枚举映射方法(使用反射)
func (*EnumMapper) ReverseMap ¶
func (em *EnumMapper) ReverseMap(target int32, defaultValue int32) int32
ReverseMap 反向映射
type Error ¶
Error 带分类的错误值 值类型实现 error,可直接用 errors.Is 比较预定义变量, 也可用 errors.As 在包装链中取回分类 [EN] A value type implementing error, so predefined vars compare with errors.Is and the category survives wrapping via errors.As
type ErrorType ¶
type ErrorType int
ErrorType 错误分类标识 数值区间 20000+ 为本库私有,与其它库的错误码空间互不干扰 [EN] Error category id; the 20000+ range is private to this library and never collides with another library's code space
const ( ErrTypeConversion ErrorType = iota + 20000 // 转换错误 ErrTypeValidation // 校验错误 ErrTypeNilValue // 空值错误 ErrTypeTypeMismatch // 类型不匹配 ErrTypeFieldMapping // 字段映射错误 ErrTypeBatch // 批量操作错误 ErrTypeDesensitize // 脱敏错误 ErrTypeRegistry // 注册中心错误 )
错误类型常量
const ErrTypeUnknown ErrorType = 0
ErrTypeUnknown 未知错误,ClassifyError 对非本库错误的返回值 单独声明而不并入下方 iota 块,否则 iota 从 1 起算会把整段错误码整体后移一位 [EN] Declared separately: folding it into the iota block below would start iota at 1 and shift every code by one
func ClassifyError ¶
ClassifyError 取出错误的分类,非本库错误返回 ErrTypeUnknown 穿透 fmt.Errorf("%w") 包装链
type GenericEnumMapper ¶
type GenericEnumMapper[S comparable, T comparable] struct { // contains filtered or unexported fields }
GenericEnumMapper 泛型枚举映射器
func NewGenericEnumMapper ¶
func NewGenericEnumMapper[S comparable, T comparable](defaultValue T) *GenericEnumMapper[S, T]
NewGenericEnumMapper 创建泛型枚举映射器
func (*GenericEnumMapper[S, T]) Map ¶
func (m *GenericEnumMapper[S, T]) Map(source S) T
Map 映射源枚举到目标枚举
func (*GenericEnumMapper[S, T]) MapSlice ¶
func (m *GenericEnumMapper[S, T]) MapSlice(sources []S) []T
MapSlice 批量映射切片
func (*GenericEnumMapper[S, T]) MapWithDefault ¶
func (m *GenericEnumMapper[S, T]) MapWithDefault(source S, defaultValue T) T
MapWithDefault 映射源枚举到目标枚举(指定默认值)
func (*GenericEnumMapper[S, T]) Register ¶
func (m *GenericEnumMapper[S, T]) Register(source S, target T) *GenericEnumMapper[S, T]
Register 注册映射关系(链式调用)
func (*GenericEnumMapper[S, T]) RegisterBatch ¶
func (m *GenericEnumMapper[S, T]) RegisterBatch(pairs map[S]T) *GenericEnumMapper[S, T]
RegisterBatch 批量注册映射关系
func (*GenericEnumMapper[S, T]) ReverseMap ¶
func (m *GenericEnumMapper[S, T]) ReverseMap(target T) (S, bool)
ReverseMap 反向映射
type IntWrapper ¶
type IntWrapper struct {
Data int
}
IntWrapper DataWrapper[T] 模式:struct{Data T} 用于触发 convertDataWrapper 慢路径(makeDataWrapperCopyFunc 对非指针 inner 返回 nil)
type Option ¶
type Option func(*Options)
Option 转换器配置选项函数
func WithAutoTimeConversion ¶
WithAutoTimeConversion 设置自动时间转换
func WithDesensitize ¶
WithDesensitize 启用/禁用脱敏,默认关闭
开启后也不是所有字段都脱敏:只处理带 desensitize tag 的字符串字段, 无 tag 的类型拷贝计划与关闭时逐字节相同,不付任何代价
作用范围是本转换器自己的顶层字段,嵌套结构体不参与 嵌套结构体的拷贝计划按「源类型+目标类型」全进程共享,承载不了 per-converter 的开关——这与 AutoTimeConversion 对嵌套同样不生效是一致的 嵌套字段需要脱敏时在输出层调 desensitize.Desensitization
[EN] Off by default. Enabling it does not mask everything: only string fields carrying a desensitize tag are touched, and a type with no tags gets byte-for-byte the same copy plan as with masking off, at no cost. The scope is this converter's own top-level fields; nested structs are excluded because their copy plans are shared process-wide by source and destination type and cannot carry a per-converter switch, exactly as AutoTimeConversion does not reach nested plans either. Mask nested fields at the output layer with desensitize.Desensitization
func WithFieldMapping ¶
WithFieldMapping 设置字段映射
func WithFieldMappings ¶
WithFieldMappings 批量设置字段映射
type Options ¶
type Options struct {
AutoTimeConversion bool // 自动时间转换开关
FieldMapping map[string]string // 字段名映射: Model字段名 -> PB字段名
TagMappingEnabled bool // 是否启用 struct tag 自动映射
TagName string // struct tag 名称(默认 pbmo)
DesensitizeEnabled bool // 是否启用脱敏(默认关闭,开启后按字段 desensitize tag 生效)
SafeMode bool // 是否启用安全模式
Concurrency int // 并发数(批量转换时使用)
BatchSize int // 批处理大小
Timeout time.Duration // 超时时间
}
Options 转换器配置项
func DefaultOptions ¶
func DefaultOptions() *Options
DefaultOptions 默认配置 FieldMapping 惰性初始化:无映射配置时不分配 map
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry 转换器注册中心 使用 syncMap 统一管理 PB ↔ Model 转换器,天然并发安全 key 为类型对结构体,热路径零字符串分配
func (*Registry) ConvertModelToPB ¶
ConvertModelToPB 通过注册中心执行 Model -> PB 转换
func (*Registry) ConvertPBToModel ¶
ConvertPBToModel 通过注册中心执行 PB -> Model 转换
func (*Registry) Lookup ¶
func (r *Registry) Lookup(pbType, modelType reflect.Type) (*BidiConverter, error)
Lookup 查找转换器
func (*Registry) LookupByInstance ¶
func (r *Registry) LookupByInstance(pb, model interface{}) (*BidiConverter, error)
LookupByInstance 通过实例查找转换器
func (*Registry) MustLookup ¶
func (r *Registry) MustLookup(pbType, modelType reflect.Type) *BidiConverter
MustLookup 查找转换器,如果不存在则 panic
func (*Registry) MustRegister ¶
func (r *Registry) MustRegister(converter *BidiConverter)
MustRegister 注册转换器,如果已存在则 panic
func (*Registry) Register ¶
func (r *Registry) Register(converter *BidiConverter) error
Register 注册转换器
func (*Registry) Unregister ¶
Unregister 移除转换器
type SafeConverter ¶
type SafeConverter struct {
*BidiConverter
}
SafeConverter 安全转换器 在转换前拦截 nil 与 typed-nil 指针,避免转换引擎 panic
func NewSafeConverter ¶
func NewSafeConverter(pbType, modelType interface{}, opts ...Option) *SafeConverter
NewSafeConverter 创建安全转换器
func (*SafeConverter) SafeConvertModelToPB ¶
func (sc *SafeConverter) SafeConvertModelToPB(model interface{}, pbPtr interface{}) error
SafeConvertModelToPB 安全的 Model -> PB 转换 自动处理 nil 与 typed-nil 指针,避免 panic
func (*SafeConverter) SafeConvertPBToModel ¶
func (sc *SafeConverter) SafeConvertPBToModel(pb interface{}, modelPtr interface{}) error
SafeConvertPBToModel 安全的 PB -> Model 转换 自动处理 nil 与 typed-nil 指针,避免 panic typed-nil 检查已覆盖 safe Access 的 IsValid 语义,不再重复构造反射包装
type TestAllSlowInnerModel ¶
type TestAllSlowInnerModel struct {
Params map[string]interface{}
}
TestAllSlowInnerModel 与 TestAllSlowInnerPB 对应的 Model
type TestAllSlowInnerPB ¶
TestAllSlowInnerPB 全 slow 字段嵌套 PB(仅含 *structpb.Struct 字段) 用于触发 convertStructPtr:makeStructPtrCopyFunc 因无 fast 字段返回 nil,该字段成为 slowEntry
type TestAllTypesModel ¶
type TestAllTypesModel struct {
IntVal int32
Int64Val int64
UintVal uint32
Uint64Val uint64
FloatVal float32
DoubleVal float64
BoolVal bool
StrVal string
BytesVal []byte
}
TestAllTypesModel 全类型测试 Model
type TestAllTypesPB ¶
type TestAllTypesPB struct {
IntVal int32
Int64Val int64
UintVal uint32
Uint64Val uint64
FloatVal float32
DoubleVal float64
BoolVal bool
StrVal string
BytesVal []byte
}
TestAllTypesPB 全类型测试 PB
type TestDataWrapperModel ¶
TestDataWrapperModel 与 TestDataWrapperPB 对应的 Model(Count 为 int 值类型)
type TestDataWrapperPB ¶
type TestDataWrapperPB struct {
Name string
Count IntWrapper
}
TestDataWrapperPB DataWrapper 测试 PB(Count 字段为 IntWrapper 值类型)
type TestInnerModel ¶
TestInnerModel 内嵌结构体 Model
type TestMapModel ¶
type TestMapStringSliceModel ¶
TestMapStringSliceModel 与 TestMapStringSlicePB 对应的 Model(Params 为 map[string][]string)
type TestMapStringSlicePB ¶
TestMapStringSlicePB 测试 map[string][]string ↔ *structpb.Struct 快路径 触发 buildStructFromMapStringSlice
type TestMapStructModel ¶
type TestMapStructModel struct {
Name string `json:"name"`
Params map[string]interface{} `json:"params"`
}
TestMapStructModel 测试 map[string]any ↔ *structpb.Struct 的 Model 模拟 sqltypes.MapAny 字段场景
type TestMapStructPB ¶
type TestMapStructPB struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Params *structpb.Struct `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"`
// contains filtered or unexported fields
}
TestMapStructPB 测试 map[string]any ↔ *structpb.Struct 的 PB Params 对应 google.protobuf.Struct 类型字段
type TestMixedInnerModel ¶
TestMixedInnerModel 与 TestMixedInnerPB 对应的 Model
type TestMixedInnerPB ¶
TestMixedInnerPB 混合字段嵌套 PB:Name(fast) + Params(slow in PB→Model) 在 PB→Model 方向,Params 为 slow(makeMapStructCopyFunc 对 *structpb.Struct→map 返回 nil), 从而触发外层 makeStructPtrCopyFunc 闭包中的 applyStructSlowEntriesUnsafe
type TestModel ¶
type TestModel struct {
ID uint64 `pbmo:"Id"`
Name string
Email string `desensitize:"email"`
Age int
Score float64
Active bool
Tags []string
}
TestModel 测试用 Model 结构体
type TestModelAllTypes ¶
type TestModelAllTypes struct {
Int int `gorm:"column:int" json:"int"`
Int8 int8 `gorm:"column:int8" json:"int8"`
Int16 int16 `gorm:"column:int16" json:"int16"`
Int32 int32 `gorm:"column:int32" json:"int32"`
Int64 int64 `gorm:"column:int64" json:"int64"`
Uint uint `gorm:"column:uint" json:"uint"`
Uint8 uint8 `gorm:"column:uint8" json:"uint8"`
Uint16 uint16 `gorm:"column:uint16" json:"uint16"`
Uint32 uint32 `gorm:"column:uint32" json:"uint32"`
Uint64 uint64 `gorm:"column:uint64" json:"uint64"`
Float32 float32 `gorm:"column:float32" json:"float32"`
Float64 float64 `gorm:"column:float64" json:"float64"`
Bool bool `gorm:"column:bool" json:"bool"`
String string `gorm:"column:string" json:"string"`
ByteSlice []byte `gorm:"column:byte_slice" json:"byte_slice"`
PtrInt *int `gorm:"column:ptr_int" json:"ptr_int"`
PtrString *string `gorm:"column:ptr_string" json:"ptr_string"`
PtrBool *bool `gorm:"column:ptr_bool" json:"ptr_bool"`
}
type TestModelForUpdates ¶
type TestModelJsonTag ¶
type TestModelNoPbmoTag ¶
type TestModelNoPbmoTag struct {
ConfigKey int `gorm:"column:config_key" json:"config_key"`
Name string `gorm:"column:name" json:"name"`
}
TestModelNoPbmoTag 无 pbmo tag 的 Model(仅 gorm/json tag), 用于测试 WithFieldMapping 在无 pbmo tag 时是否生效
type TestModelUnexported ¶
type TestModelUnexported struct {
Name string `gorm:"column:name" json:"name"`
// contains filtered or unexported fields
}
type TestModelWithMapping ¶
type TestModelWithMapping struct {
ID uint64 `pbmo:"ClientId"`
Name string `pbmo:"UserName"`
Email string `pbmo:"UserEmail"`
}
TestModelWithMapping 测试用 Model 结构体(需要字段映射)
type TestNamedSliceModel ¶
type TestNamedSliceModel struct {
Name string
Tags TestStringSlice
Items TestStringSlice
}
TestNamedSliceModel 命名切片测试 Model(使用命名切片类型)
type TestNamedSlicePB ¶
TestNamedSlicePB 命名切片测试 PB(使用 []string)
type TestNestModel ¶
type TestNestModel struct {
Name string
Detail *TestSimpleModel
}
TestNestModel 嵌套测试 Model
type TestNestedAutoModel ¶
type TestNestedAutoModel struct {
Name string
Inner *TestInnerModel
}
TestNestedAutoModel 嵌套自动转换 Model
type TestNestedAutoPB ¶
type TestNestedAutoPB struct {
Name string
Inner *TestInnerPB
}
TestNestedAutoPB 嵌套自动转换 PB
type TestOuterAllSlowModel ¶
type TestOuterAllSlowModel struct {
Name string
Inner *TestAllSlowInnerModel
}
TestOuterAllSlowModel 与 TestOuterAllSlowPB 对应的 Model
type TestOuterAllSlowPB ¶
type TestOuterAllSlowPB struct {
Name string
Inner *TestAllSlowInnerPB
}
TestOuterAllSlowPB 外层包含全 slow 嵌套指针(触发 convertStructPtr)
type TestOuterMixedModel ¶
type TestOuterMixedModel struct {
Name string
Inner *TestMixedInnerModel
}
TestOuterMixedModel 与 TestOuterMixedPB 对应的 Model
type TestOuterMixedPB ¶
type TestOuterMixedPB struct {
Name string
Inner *TestMixedInnerPB
}
TestOuterMixedPB 外层包含混合嵌套指针(触发 applyStructSlowEntriesUnsafe)
type TestOuterValueStructModel ¶
type TestOuterValueStructModel struct {
Name string
Inner TestAllSlowInnerModel
}
TestOuterValueStructModel 与 TestOuterValueStructPB 对应的 Model
type TestOuterValueStructPB ¶
type TestOuterValueStructPB struct {
Name string
Inner TestAllSlowInnerPB
}
TestOuterValueStructPB 外层包含值类型嵌套结构体(触发 convertStruct,非指针)
type TestPB ¶
type TestPB struct {
Id uint64
Name string
Email string
Age int32
Score float64
Active bool
Tags []string
}
TestPB 测试用 PB 结构体
type TestPBNoPbmoTag ¶
TestPBNoPbmoTag 对应的 PB,字段名与 Model 不同,需要 FieldMapping
type TestPBUpdatesEmpty ¶
type TestPBUpdatesEmpty struct {
// contains filtered or unexported fields
}
type TestPBUpdatesMsg ¶
type TestPBUpdatesMsg struct {
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
HostStatus int32 `protobuf:"varint,2,opt,name=host_status,json=hostStatus,proto3" json:"host_status,omitempty"`
TenantId string `protobuf:"bytes,3,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"`
RegionCode string `protobuf:"bytes,4,opt,name=region_code,json=regionCode,proto3" json:"region_code,omitempty"`
IsProxied *wrapperspb.BoolValue `protobuf:"varint,5,opt,name=is_proxied,json=isProxied,proto3" json:"is_proxied,omitempty"`
DisplayName *wrapperspb.StringValue `protobuf:"bytes,6,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
Priority *wrapperspb.Int32Value `protobuf:"varint,7,opt,name=priority,json=priority,proto3" json:"priority,omitempty"`
Score *wrapperspb.DoubleValue `protobuf:"varint,8,opt,name=score,json=score,proto3" json:"score,omitempty"`
Metadata map[string]string `` /* 143-byte string literal not displayed */
// contains filtered or unexported fields
}
type TestPBUpdatesNoTag ¶
type TestPBWithMapping ¶
TestPBWithMapping 测试用 PB 结构体(需要字段映射)
type TestSimpleModel ¶
TestSimpleModel 简单测试 Model
type TestSingleFieldModel ¶
type TestSingleFieldModel struct {
Name string
}
TestSingleFieldModel 单字段 Model
type TestSliceStructModel ¶
type TestSliceStructModel struct {
Name string
Items []*TestAllSlowInnerModel
}
TestSliceStructModel 与 TestSliceStructPB 对应的 Model
type TestSliceStructPB ¶
type TestSliceStructPB struct {
Name string
Items []*TestAllSlowInnerPB
}
TestSliceStructPB 切片元素为不同结构体指针(触发 convertSlice/convertElement) 元素类型 *TestAllSlowInnerPB → *TestAllSlowInnerModel 不 ConvertibleTo, 且元素结构体全 slow,使 makeSliceCopyFunc 返回 nil
type TestSliceValueStructModel ¶
type TestSliceValueStructModel struct {
Name string
Items []TestAllSlowInnerModel
}
TestSliceValueStructModel 与 TestSliceValueStructPB 对应的 Model
type TestSliceValueStructPB ¶
type TestSliceValueStructPB struct {
Name string
Items []TestAllSlowInnerPB
}
TestSliceValueStructPB 切片元素为值结构体(覆盖 convertSlice 元素为值类型的分支)
type TestTimePtrModel ¶
TestTimePtrModel 时间指针测试 Model
type TestTimePtrPB ¶
type TestTimePtrPB struct {
Name string
ScheduledAt *timestamppb.Timestamp
ReleasedAt *timestamppb.Timestamp
}
TestTimePtrPB 时间指针测试 PB
type TestTimeZeroModel ¶
TestTimeZeroModel 时间零值测试 Model
type TestTimeZeroPB ¶
type TestTimeZeroPB struct {
Name string
CreatedAt *timestamppb.Timestamp
UpdatedAt *timestamppb.Timestamp
}
TestTimeZeroPB 时间零值测试 PB
type TestWrapperFieldModel ¶
TestWrapperFieldModel Wrapper 字段测试 Model
type TestWrapperFieldPB ¶
type TestWrapperFieldPB struct {
Name string
MinVal *wrapperspb.Int32Value
MaxVal *wrapperspb.Int32Value
}
TestWrapperFieldPB Wrapper 字段测试 PB
type TestWrapperValueModel ¶
type TestWrapperValuePB ¶
type TestWrapperValuePB struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
IsActive *wrapperspb.BoolValue `protobuf:"varint,2,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"`
Count *wrapperspb.Int32Value `protobuf:"varint,3,opt,name=count,proto3" json:"count,omitempty"`
Score *wrapperspb.DoubleValue `protobuf:"varint,4,opt,name=score,proto3" json:"score,omitempty"`
Label *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=label,proto3" json:"label,omitempty"`
// contains filtered or unexported fields
}
type TransformerFunc ¶
type TransformerFunc func(interface{}) interface{}
TransformerFunc 字段转换函数类型 输入原始字段值,输出转换后的值
type TransformerRegistry ¶
type TransformerRegistry struct {
// contains filtered or unexported fields
}
TransformerRegistry 字段转换器注册表 封装 sync.Map 提供类型安全的字段转换器管理,天然并发安全 count: 原子计数器,避免 Count() 使用 sync.Map.Range() 的 O(n) 开销
func NewTransformerRegistry ¶
func NewTransformerRegistry() *TransformerRegistry
NewTransformerRegistry 创建字段转换器注册表
func (*TransformerRegistry) Clone ¶
func (tr *TransformerRegistry) Clone() *TransformerRegistry
Clone 克隆转换器注册表
func (*TransformerRegistry) Fields ¶
func (tr *TransformerRegistry) Fields() []string
Fields 获取所有已注册的字段名
func (*TransformerRegistry) Has ¶
func (tr *TransformerRegistry) Has(field string) bool
Has 检查字段是否有注册的转换器
func (*TransformerRegistry) Lookup ¶
func (tr *TransformerRegistry) Lookup(field string) (TransformerFunc, bool)
Lookup 查找字段转换器
func (*TransformerRegistry) Register ¶
func (tr *TransformerRegistry) Register(field string, fn TransformerFunc)
Register 注册字段转换器
func (*TransformerRegistry) RegisterBatch ¶
func (tr *TransformerRegistry) RegisterBatch(transformers map[string]TransformerFunc)
RegisterBatch 批量注册字段转换器
func (*TransformerRegistry) Remove ¶
func (tr *TransformerRegistry) Remove(field string)
Remove 移除字段转换器
type UpdatesBuilder ¶
type UpdatesBuilder struct {
// contains filtered or unexported fields
}
UpdatesBuilder 更新字段构建器
func (*UpdatesBuilder) Build ¶
func (b *UpdatesBuilder) Build() map[string]interface{}
func (*UpdatesBuilder) Clear ¶
func (b *UpdatesBuilder) Clear() *UpdatesBuilder
func (*UpdatesBuilder) Delete ¶
func (b *UpdatesBuilder) Delete(key string) *UpdatesBuilder
func (*UpdatesBuilder) Has ¶
func (b *UpdatesBuilder) Has(key string) bool
func (*UpdatesBuilder) IsEmpty ¶
func (b *UpdatesBuilder) IsEmpty() bool
func (*UpdatesBuilder) Len ¶
func (b *UpdatesBuilder) Len() int
func (*UpdatesBuilder) Merge ¶
func (b *UpdatesBuilder) Merge(other *UpdatesBuilder) *UpdatesBuilder
func (*UpdatesBuilder) Set ¶
func (b *UpdatesBuilder) Set(key string, value interface{}) *UpdatesBuilder
func (*UpdatesBuilder) SetBoolVal ¶
func (b *UpdatesBuilder) SetBoolVal(key string, val *wrapperspb.BoolValue) *UpdatesBuilder
func (*UpdatesBuilder) SetDoubleVal ¶
func (b *UpdatesBuilder) SetDoubleVal(key string, val *wrapperspb.DoubleValue) *UpdatesBuilder
func (*UpdatesBuilder) SetFloatVal ¶
func (b *UpdatesBuilder) SetFloatVal(key string, val *wrapperspb.FloatValue) *UpdatesBuilder
func (*UpdatesBuilder) SetIf ¶
func (b *UpdatesBuilder) SetIf(condition bool, key string, value interface{}) *UpdatesBuilder
func (*UpdatesBuilder) SetIfNotEmpty ¶
func (b *UpdatesBuilder) SetIfNotEmpty(key string, value interface{}) *UpdatesBuilder
SetIfNotEmpty 设置字符串字段(非空时) 支持 string 和 *wrapperspb.StringValue 类型 使用 IsEmptyValue 进行严格的空值判断:
- 过滤空字符串、空白字符(空格、tab、换行等)
- 过滤 "null"、"undefined" 字符串(不区分大小写)
- 过滤 nil 值
func (*UpdatesBuilder) SetIfNotNil ¶
func (b *UpdatesBuilder) SetIfNotNil(key string, value interface{}) *UpdatesBuilder
func (*UpdatesBuilder) SetIfNotZero ¶
func (b *UpdatesBuilder) SetIfNotZero(key string, value interface{}) *UpdatesBuilder
func (*UpdatesBuilder) SetInt32Val ¶
func (b *UpdatesBuilder) SetInt32Val(key string, val *wrapperspb.Int32Value) *UpdatesBuilder
func (*UpdatesBuilder) SetInt64Val ¶
func (b *UpdatesBuilder) SetInt64Val(key string, val *wrapperspb.Int64Value) *UpdatesBuilder
func (*UpdatesBuilder) SetJSON ¶
func (b *UpdatesBuilder) SetJSON(key string, value string, defaultJSON ...string) *UpdatesBuilder
func (*UpdatesBuilder) SetJSONSlice ¶
func (b *UpdatesBuilder) SetJSONSlice(key string, value interface{}) *UpdatesBuilder
func (*UpdatesBuilder) SetJSONVal ¶
func (b *UpdatesBuilder) SetJSONVal(key string, val *wrapperspb.StringValue, defaultJSON ...string) *UpdatesBuilder
func (*UpdatesBuilder) SetNull ¶
func (b *UpdatesBuilder) SetNull(key string) *UpdatesBuilder
SetNull 将字段设置为 NULL(等价于 Set(key, nil)) 用于将数据库字段清空的语义化写法,如 SetNull("callback_at") 替代 Set("callback_at", time.Time{})
func (*UpdatesBuilder) SetString ¶
func (b *UpdatesBuilder) SetString(key string, val string) *UpdatesBuilder
SetString 设置 plain string 字段(空字符串/空白时跳过) 用于 proto3 非 wrapper 的 string 字段,区分"未发送(默认空字符串)"和"有值"
func (*UpdatesBuilder) SetStringVal ¶
func (b *UpdatesBuilder) SetStringVal(key string, val *wrapperspb.StringValue) *UpdatesBuilder
func (*UpdatesBuilder) SetStringValAny ¶
func (b *UpdatesBuilder) SetStringValAny(key string, val *wrapperspb.StringValue) *UpdatesBuilder
func (*UpdatesBuilder) SetStringValOrEmpty ¶
func (b *UpdatesBuilder) SetStringValOrEmpty(key string, val *wrapperspb.StringValue) *UpdatesBuilder
SetStringValOrEmpty 设置字段(nil 也写入空字符串,用于全量覆盖场景) 与 SetStringValAny 的区别:nil 不跳过,而是写入 ""
func (*UpdatesBuilder) String ¶
func (b *UpdatesBuilder) String() string