github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/msgfmt/jsonfmt/encoder_map.go (about)

     1  package jsonfmt
     2  
     3  import (
     4  	"unsafe"
     5  	"context"
     6  	"github.com/v2pro/plz/reflect2"
     7  )
     8  
     9  type mapEncoder struct {
    10  	keyEncoder  Encoder
    11  	elemEncoder Encoder
    12  	mapType     *reflect2.UnsafeMapType
    13  }
    14  
    15  func (encoder *mapEncoder) Encode(ctx context.Context, space []byte, ptr unsafe.Pointer) []byte {
    16  	if *(*unsafe.Pointer)(ptr) == nil {
    17  		return append(space, 'n', 'u', 'l', 'l')
    18  	}
    19  	iter := encoder.mapType.UnsafeIterate(ptr)
    20  	space = append(space, '{')
    21  	for i := 0; iter.HasNext(); i++ {
    22  		if i != 0 {
    23  			space = append(space, ',')
    24  		}
    25  		key, elem := iter.UnsafeNext()
    26  		space = encoder.keyEncoder.Encode(ctx, space, key)
    27  		space = encoder.elemEncoder.Encode(ctx, space, elem)
    28  	}
    29  	space = append(space, '}')
    30  	return space
    31  }
    32  
    33  type mapNumberKeyEncoder struct {
    34  	valEncoder Encoder
    35  }
    36  
    37  func (encoder *mapNumberKeyEncoder) Encode(ctx context.Context, space []byte, ptr unsafe.Pointer) []byte {
    38  	space = append(space, '"')
    39  	space = encoder.valEncoder.Encode(ctx, space, ptr)
    40  	space = append(space, '"', ':')
    41  	return space
    42  }
    43  
    44  type mapStringKeyEncoder struct {
    45  	valEncoder Encoder
    46  }
    47  
    48  func (encoder *mapStringKeyEncoder) Encode(ctx context.Context, space []byte, ptr unsafe.Pointer) []byte {
    49  	space = encoder.valEncoder.Encode(ctx, space, ptr)
    50  	space = append(space, ':')
    51  	return space
    52  }
    53  
    54  type mapInterfaceKeyEncoder struct {
    55  	cfg    *frozenConfig
    56  	prefix string
    57  }
    58  
    59  func (encoder *mapInterfaceKeyEncoder) Encode(ctx context.Context, space []byte, ptr unsafe.Pointer) []byte {
    60  	keyObj := *(*interface{})(ptr)
    61  	keyEncoder := encoderOfMapKey(encoder.cfg, encoder.prefix, reflect2.TypeOf(keyObj))
    62  	return keyEncoder.Encode(ctx, space, reflect2.PtrOf(keyObj))
    63  }