Documentation
¶
Overview ¶
* @Author: kamalyes 501893067@qq.com * @Date: 2025-02-28 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-05-13 13:15:15 * @FilePath: \go-toolbox\pkg\serializer\json.go * @Description: JSON解析和转换工具 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
* @Author: kamalyes 501893067@qq.com * @Date: 2025-02-28 00:00:00 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-05-13 13:15:15 * @FilePath: \go-toolbox\pkg\serializer\json_errors.go * @Description: JSON错误定义 * * Copyright (c) 2025 by kamalyes, All Rights Reserved.
* @Author: kamalyes 501893067@qq.com * @Date: 2026-05-11 13:20:41 * @LastEditors: kamalyes 501893067@qq.com * @LastEditTime: 2026-05-30 20:15:55 * @FilePath: \go-toolbox\pkg\serializer\proto_json.go * @Description: 序列化 protobuf 消息为 JSON 字符串
Index ¶
- Constants
- Variables
- func FromJSON[T any](jsonStr string) T
- func IsJSONExpectedArrayError(err error) bool
- func IsJSONExpectedArrayNextError(err error) bool
- func IsJSONExpectedObjectError(err error) bool
- func IsJSONExpectedObjectKeySeparatorError(err error) bool
- func IsJSONExpectedObjectNextError(err error) bool
- func IsJSONInvalidUnknownFieldValueError(err error) bool
- func IsJSONMapKeyUnsupportedError(err error) bool
- func IsJSONNilTargetError(err error) bool
- func IsJSONUnexpectedEndObjectError(err error) bool
- func JSONMarshal[T any](value T) ([]byte, error)
- func JSONUnmarshal[T any](data []byte, target *T) error
- func LenientProtoJSONUnmarshal(data []byte, msg proto.Message) error
- func NewJSONArrayTooLongError(items int, capacity int) error
- func NewJSONExpectedArrayError() error
- func NewJSONExpectedArrayNextError() error
- func NewJSONExpectedObjectError() error
- func NewJSONExpectedObjectKeySeparatorError() error
- func NewJSONExpectedObjectNextError() error
- func NewJSONFieldError(name string, err error) error
- func NewJSONInvalidUnknownFieldValueError() error
- func NewJSONItemError(index int, err error) error
- func NewJSONKeyError(key string, err error) error
- func NewJSONMapKeyUnsupportedError(keyType string) error
- func NewJSONNilTargetError() error
- func NewJSONUnexpectedEndObjectError() error
- func NormalizeJSONDefault(defaultValue ...string) string
- func NormalizeJSONText(value string, defaultValue ...string) string
- func ProtoJSONMarshal(m interface{}) (string, error)
- func ProtoJSONUnmarshal(a, b interface{}) error
- func ToJSON[T any](v T) string
- type BenchmarkResult
- type CompressionType
- type LenientProtoJSONOptions
- type SerializeType
- type Serializer
- func (s *Serializer[T]) Benchmark(obj T, iterations int) (*BenchmarkResult, error)
- func (s *Serializer[T]) Decode(data []byte) (T, error)
- func (s *Serializer[T]) DecodeFromString(encoded string) (T, error)
- func (s *Serializer[T]) Encode(obj T) ([]byte, error)
- func (s *Serializer[T]) EncodeToString(obj T) (string, error)
- func (s *Serializer[T]) GetStats(obj T) (*Stats, error)
- func (s *Serializer[T]) WithBase64(enable bool) *Serializer[T]
- func (s *Serializer[T]) WithCompression(cType CompressionType) *Serializer[T]
- func (s *Serializer[T]) WithCustomDecoder(decoder func([]byte) (T, error)) *Serializer[T]
- func (s *Serializer[T]) WithCustomEncoder(encoder func(T) ([]byte, error)) *Serializer[T]
- func (s *Serializer[T]) WithType(sType SerializeType) *Serializer[T]
- type Stats
Constants ¶
const DefaultJSONText = "{}"
Variables ¶
var ( ErrJSONNilTarget = errors.New("serializer json: nil target") ErrJSONUnexpectedEndObject = errors.New("serializer json: unexpected end of object") ErrJSONExpectedObject = errors.New("serializer json: expected object") ErrJSONExpectedArray = errors.New("serializer json: expected array") ErrJSONExpectedObjectKeySeparator = errors.New("serializer json: expected ':' after object key") ErrJSONInvalidUnknownFieldValue = errors.New("serializer json: invalid unknown field value") ErrJSONExpectedObjectNext = errors.New("serializer json: expected ',' or '}' after object value") ErrJSONExpectedArrayNext = errors.New("serializer json: expected ',' or ']' after array item") ErrJSONMapKeyUnsupported = errors.New("serializer json: proto-aware map only supports string keys") )
Functions ¶
func IsJSONExpectedArrayError ¶
IsJSONExpectedArrayError 判断错误是否为期望 JSON 数组错误
func IsJSONExpectedArrayNextError ¶
IsJSONExpectedArrayNextError 判断错误是否为数组元素后缺少逗号或结束符
func IsJSONExpectedObjectError ¶
IsJSONExpectedObjectError 判断错误是否为期望 JSON 对象错误
func IsJSONExpectedObjectKeySeparatorError ¶
IsJSONExpectedObjectKeySeparatorError 判断错误是否为对象键值分隔符错误
func IsJSONExpectedObjectNextError ¶
IsJSONExpectedObjectNextError 判断错误是否为对象值后缺少逗号或结束符
func IsJSONInvalidUnknownFieldValueError ¶
IsJSONInvalidUnknownFieldValueError 判断错误是否为未知字段值非法
func IsJSONMapKeyUnsupportedError ¶
IsJSONMapKeyUnsupportedError 判断错误是否为 proto-aware map 键类型不支持
func IsJSONNilTargetError ¶
IsJSONNilTargetError 判断错误是否为 JSON 反序列化目标为空
func IsJSONUnexpectedEndObjectError ¶
IsJSONUnexpectedEndObjectError 判断错误是否为 JSON 对象意外结束
func JSONMarshal ¶
JSONMarshal 使用标准 JSON 或 proto-aware JSON 序列化值
func JSONUnmarshal ¶
JSONUnmarshal 使用标准 JSON 或 proto-aware JSON 反序列化到目标值
func LenientProtoJSONUnmarshal ¶
LenientProtoJSONUnmarshal 执行宽松的 Protobuf JSON 反序列化
该函数是 protojson.Unmarshal 的兼容增强版本:
- 首先尝试使用默认选项进行标准 protojson.Unmarshal;
- 如果失败且错误是「字符串给了数值字段」类型,自动将 JSON 数据中的数字字符串转换为 JSON 数字后重试;
- 如果转换后仍失败,返回第一次的原始错误(避免转换产生的误导性错误信息)
性能特征:
- 标准请求(数字以正确形式传递):1次 protojson.Unmarshal,零额外开销
- 非数字类型错误(语法错误/缺字段等):1次 protojson.Unmarshal + O(1) 错误字符串前缀匹配
- 数字字符串场景(bug case):2次 protojson.Unmarshal + 1次 JSON 转换
支持兼容的类型:
- int64 / sint64 / sfixed64:支持字符串形式的有符号 64 位整数
- uint64 / fixed64:支持字符串形式的无符号 64 位整数
- int32 / uint32 / 等 32 位整数:同样支持字符串形式
- float / double:支持字符串形式的浮点数(如 "3.14"、"1e10")
安全保障:
- 非数字字符串(如 "hello"、"ABC123")不会被错误转换;
- 如果标准 Unmarshal 一次性成功,不会有额外性能开销;
- 若重试也失败,返回第一次解析的原始错误,便于排查真实问题
参数:
- data: JSON 格式的字节切片
- msg: 目标 proto.Message 指针,用于接收反序列化结果
返回值:
- error: 反序列化失败时返回错误;成功返回 nil
func NewJSONArrayTooLongError ¶
NewJSONArrayTooLongError 创建 JSON 数组长度超过目标数组长度错误
func NewJSONExpectedArrayError ¶
func NewJSONExpectedArrayError() error
NewJSONExpectedArrayError 创建期望 JSON 数组错误
func NewJSONExpectedArrayNextError ¶
func NewJSONExpectedArrayNextError() error
NewJSONExpectedArrayNextError 创建数组元素后缺少逗号或结束符错误
func NewJSONExpectedObjectError ¶
func NewJSONExpectedObjectError() error
NewJSONExpectedObjectError 创建期望 JSON 对象错误
func NewJSONExpectedObjectKeySeparatorError ¶
func NewJSONExpectedObjectKeySeparatorError() error
NewJSONExpectedObjectKeySeparatorError 创建对象键值分隔符错误
func NewJSONExpectedObjectNextError ¶
func NewJSONExpectedObjectNextError() error
NewJSONExpectedObjectNextError 创建对象值后缺少逗号或结束符错误
func NewJSONFieldError ¶
NewJSONFieldError 包装字段级 JSON 错误,保留字段名上下文
func NewJSONInvalidUnknownFieldValueError ¶
func NewJSONInvalidUnknownFieldValueError() error
NewJSONInvalidUnknownFieldValueError 创建未知字段值非法错误
func NewJSONItemError ¶
NewJSONItemError 包装数组或切片元素级 JSON 错误,保留下标上下文
func NewJSONKeyError ¶
NewJSONKeyError 包装 map 键对应值的 JSON 错误,保留键上下文
func NewJSONMapKeyUnsupportedError ¶
NewJSONMapKeyUnsupportedError 创建 proto-aware map 键类型不支持错误
func NewJSONNilTargetError ¶
func NewJSONNilTargetError() error
NewJSONNilTargetError 创建 JSON 反序列化目标为空错误
func NewJSONUnexpectedEndObjectError ¶
func NewJSONUnexpectedEndObjectError() error
NewJSONUnexpectedEndObjectError 创建 JSON 对象意外结束错误
func NormalizeJSONDefault ¶
NormalizeJSONDefault 返回默认 JSON 字符串,确保 JSON 格式正确
func NormalizeJSONText ¶
NormalizeJSONText 在 JSON 字符串前添加默认值,确保 JSON 格式正确
func ProtoJSONMarshal ¶
ProtoJSONMarshal 序列化 protobuf 消息为 JSON 字符串 支持传入 proto.Message 或 interface{} (会自动进行类型断言)
func ProtoJSONUnmarshal ¶
func ProtoJSONUnmarshal(a, b interface{}) error
ProtoJSONUnmarshal 反序列化 JSON 字符串为 protobuf 消息 两个参数均为 interface{},内部自动识别 proto.Message 和 JSON 字符串,兼容任意顺序
Types ¶
type BenchmarkResult ¶
type BenchmarkResult struct {
EncodeTime time.Duration `json:"encode_time"`
DecodeTime time.Duration `json:"decode_time"`
DataSize int `json:"data_size"`
Type SerializeType `json:"type"`
Compression CompressionType `json:"compression"`
Iterations int `json:"iterations"`
}
BenchmarkResult 基准测试结果
type CompressionType ¶
type CompressionType byte
CompressionType 压缩类型
const ( // CompressionNone 无压缩 CompressionNone CompressionType = 0x00 // CompressionGzip Gzip压缩(基于zipx) CompressionGzip CompressionType = 0x01 // CompressionZlib Zlib压缩(基于zipx) CompressionZlib CompressionType = 0x02 // CompressionZstd Zstd压缩(预留) CompressionZstd CompressionType = 0x03 )
type LenientProtoJSONOptions ¶
type LenientProtoJSONOptions struct {
// DiscardUnknown 控制是否忽略未知字段
// 如果为 true,反序列化时遇到未在 proto 中定义的字段不会报错
DiscardUnknown bool
// AllowPartial 控制是否允许部分反序列化
// 如果为 true,缺少必填字段时不会报错
AllowPartial bool
}
LenientProtoJSONOptions 宽松 Protobuf JSON 反序列化选项
封装 protojson.UnmarshalOptions,在标准解析失败时自动执行数字字符串转换并重试 字段与 protojson.UnmarshalOptions 保持一致,便于按需配置
func (LenientProtoJSONOptions) ToProtojsonOptions ¶
func (o LenientProtoJSONOptions) ToProtojsonOptions() protojson.UnmarshalOptions
ToProtojsonOptions 转换为标准 protojson.UnmarshalOptions 用于需要直接使用 protojson 原生选项的场景
func (LenientProtoJSONOptions) Unmarshal ¶
func (o LenientProtoJSONOptions) Unmarshal(data []byte, msg proto.Message) error
Unmarshal 使用当前选项执行宽松的 Protobuf JSON 反序列化
执行流程:
- 使用配置的 protojson.UnmarshalOptions 尝试标准反序列化;
- 若成功直接返回 nil(零额外开销路径);
- 若失败,通过 isNumericTypeMismatchErr 快速判断是否为数字类型不匹配错误;
- 若不是数字类型错误(如语法错误、缺字段等),直接返回原始错误,避免无效转换;
- 若是数字类型错误,调用 jsonx.ConvertNumericStrings 将数字字符串转换为 JSON 数字;
- 若转换后的数据与原始数据不同(即存在需要转换的数字字符串),使用转换后的数据重试一次;
- 若重试成功返回 nil;否则返回第一次解析的原始错误
参数:
- data: JSON 格式的字节切片
- msg: 目标 proto.Message 指针
返回值:
- error: 反序列化失败时返回错误
type SerializeType ¶
type SerializeType byte
SerializeType 序列化类型
const ( // TypeJSON JSON序列化(通用兼容) TypeJSON SerializeType = 0x01 // TypeGob Gob二进制序列化(Go优化) TypeGob SerializeType = 0x02 // TypeMsgpack MessagePack序列化(跨语言) TypeMsgpack SerializeType = 0x03 // TypeProtobuf Protobuf序列化(最高效) TypeProtobuf SerializeType = 0x04 )
type Serializer ¶
type Serializer[T any] struct { // contains filtered or unexported fields }
Serializer 通用泛型序列化器
func NewUltraCompact ¶
func NewUltraCompact[T any]() *Serializer[T]
NewUltraCompact 创建超紧凑序列化器(JSON + Gzip + Base64,兼容性最佳)
func NewZlibCompact ¶
func NewZlibCompact[T any]() *Serializer[T]
NewZlibCompact 创建Zlib压缩序列化器(Gob + Zlib + Base64)
func (*Serializer[T]) Benchmark ¶
func (s *Serializer[T]) Benchmark(obj T, iterations int) (*BenchmarkResult, error)
Benchmark 性能基准测试
func (*Serializer[T]) DecodeFromString ¶
func (s *Serializer[T]) DecodeFromString(encoded string) (T, error)
DecodeFromString 从字符串反序列化(优化版本)
func (*Serializer[T]) EncodeToString ¶
func (s *Serializer[T]) EncodeToString(obj T) (string, error)
EncodeToString 序列化为字符串
func (*Serializer[T]) GetStats ¶
func (s *Serializer[T]) GetStats(obj T) (*Stats, error)
GetStats 获取序列化统计信息
func (*Serializer[T]) WithBase64 ¶
func (s *Serializer[T]) WithBase64(enable bool) *Serializer[T]
WithBase64 启用/禁用Base64编码
func (*Serializer[T]) WithCompression ¶
func (s *Serializer[T]) WithCompression(cType CompressionType) *Serializer[T]
WithCompression 设置压缩类型
func (*Serializer[T]) WithCustomDecoder ¶
func (s *Serializer[T]) WithCustomDecoder(decoder func([]byte) (T, error)) *Serializer[T]
WithCustomDecoder 设置自定义解码器
func (*Serializer[T]) WithCustomEncoder ¶
func (s *Serializer[T]) WithCustomEncoder(encoder func(T) ([]byte, error)) *Serializer[T]
WithCustomEncoder 设置自定义编码器
func (*Serializer[T]) WithType ¶
func (s *Serializer[T]) WithType(sType SerializeType) *Serializer[T]
WithType 设置序列化类型
type Stats ¶
type Stats struct {
Type SerializeType `json:"type"`
Compression CompressionType `json:"compression"`
Base64 bool `json:"base64"`
CurrentSize int `json:"current_size"`
JSONSize int `json:"json_size"`
GobSize int `json:"gob_size"`
CompressionRatio float64 `json:"compression_ratio"`
SpaceSaved int `json:"space_saved"`
SpaceSavedPercent float64 `json:"space_saved_percent"`
}
Stats 序列化统计信息