in internal/encoding/encode.go [407:521]
func writeMap(wr *buffer.Buffer, m any) error {
startIdx := wr.Len()
wr.Append([]byte{
byte(TypeCodeMap32), // type
0, 0, 0, 0, // size placeholder
0, 0, 0, 0, // length placeholder
})
var pairs int
switch m := m.(type) {
case map[any]any:
pairs = len(m) * 2
for key, val := range m {
err := Marshal(wr, key)
if err != nil {
return err
}
err = Marshal(wr, val)
if err != nil {
return err
}
}
case map[string]any:
pairs = len(m) * 2
for key, val := range m {
err := writeString(wr, key)
if err != nil {
return err
}
err = Marshal(wr, val)
if err != nil {
return err
}
}
case map[Symbol]any:
pairs = len(m) * 2
for key, val := range m {
err := key.Marshal(wr)
if err != nil {
return err
}
err = Marshal(wr, val)
if err != nil {
return err
}
}
case Unsettled:
pairs = len(m) * 2
for key, val := range m {
err := writeString(wr, key)
if err != nil {
return err
}
err = Marshal(wr, val)
if err != nil {
return err
}
}
case Filter:
pairs = len(m) * 2
for key, val := range m {
err := key.Marshal(wr)
if err != nil {
return err
}
err = val.Marshal(wr)
if err != nil {
return err
}
}
case Annotations:
pairs = len(m) * 2
for key, val := range m {
switch key := key.(type) {
case string:
err := Symbol(key).Marshal(wr)
if err != nil {
return err
}
case Symbol:
err := key.Marshal(wr)
if err != nil {
return err
}
case int64:
writeInt64(wr, key)
case int:
writeInt64(wr, int64(key))
default:
return fmt.Errorf("unsupported Annotations key type %T", key)
}
err := Marshal(wr, val)
if err != nil {
return err
}
}
default:
return fmt.Errorf("unsupported map type %T", m)
}
if uint(pairs) > math.MaxUint32-4 {
return errors.New("map contains too many elements")
}
// overwrite placeholder size and length
bytes := wr.Bytes()[startIdx+1 : startIdx+9]
_ = bytes[7] // bounds check hint
length := wr.Len() - startIdx - 1 - 4 // -1 for type, -4 for length
binary.BigEndian.PutUint32(bytes[:4], uint32(length))
binary.BigEndian.PutUint32(bytes[4:8], uint32(pairs))
return nil
}