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 }