func writeMap()

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
}