package pgtype
import (
)
type JSONBCodec struct {
Marshal func(v any) ([]byte, error)
Unmarshal func(data []byte, v any) error
}
func (*JSONBCodec) ( int16) bool {
return == TextFormatCode || == BinaryFormatCode
}
func (*JSONBCodec) () int16 {
return TextFormatCode
}
func ( *JSONBCodec) ( *Map, uint32, int16, any) EncodePlan {
switch {
case BinaryFormatCode:
:= (&JSONCodec{Marshal: .Marshal, Unmarshal: .Unmarshal}).PlanEncode(, , TextFormatCode, )
if != nil {
return &encodePlanJSONBCodecBinaryWrapper{textPlan: }
}
case TextFormatCode:
return (&JSONCodec{Marshal: .Marshal, Unmarshal: .Unmarshal}).PlanEncode(, , , )
}
return nil
}
type encodePlanJSONBCodecBinaryWrapper struct {
textPlan EncodePlan
}
func ( *encodePlanJSONBCodecBinaryWrapper) ( any, []byte) ( []byte, error) {
= append(, 1)
return .textPlan.Encode(, )
}
func ( *JSONBCodec) ( *Map, uint32, int16, any) ScanPlan {
switch {
case BinaryFormatCode:
:= (&JSONCodec{Marshal: .Marshal, Unmarshal: .Unmarshal}).PlanScan(, , TextFormatCode, )
if != nil {
return &scanPlanJSONBCodecBinaryUnwrapper{textPlan: }
}
case TextFormatCode:
return (&JSONCodec{Marshal: .Marshal, Unmarshal: .Unmarshal}).PlanScan(, , , )
}
return nil
}
type scanPlanJSONBCodecBinaryUnwrapper struct {
textPlan ScanPlan
}
func ( *scanPlanJSONBCodecBinaryUnwrapper) ( []byte, any) error {
if == nil {
return .textPlan.Scan(, )
}
if len() == 0 {
return fmt.Errorf("jsonb too short")
}
if [0] != 1 {
return fmt.Errorf("unknown jsonb version number %d", [0])
}
return .textPlan.Scan([1:], )
}
func ( *JSONBCodec) ( *Map, uint32, int16, []byte) (driver.Value, error) {
if == nil {
return nil, nil
}
switch {
case BinaryFormatCode:
if len() == 0 {
return nil, fmt.Errorf("jsonb too short")
}
if [0] != 1 {
return nil, fmt.Errorf("unknown jsonb version number %d", [0])
}
:= make([]byte, len()-1)
copy(, [1:])
return , nil
case TextFormatCode:
:= make([]byte, len())
copy(, )
return , nil
default:
return nil, fmt.Errorf("unknown format code: %v", )
}
}
func ( *JSONBCodec) ( *Map, uint32, int16, []byte) (any, error) {
if == nil {
return nil, nil
}
switch {
case BinaryFormatCode:
if len() == 0 {
return nil, fmt.Errorf("jsonb too short")
}
if [0] != 1 {
return nil, fmt.Errorf("unknown jsonb version number %d", [0])
}
= [1:]
case TextFormatCode:
default:
return nil, fmt.Errorf("unknown format code: %v", )
}
var any
:= .Unmarshal(, &)
return ,
}