func (c Copier) AppendValueBytes(dst []byte, src ValueReader) (bsontype.Type, []byte, error) {
	if br, ok := src.(BytesReader); ok {
		return br.ReadValueBytes(dst)
	}
	vw := vwPool.Get().(*valueWriter)
	defer vwPool.Put(vw)
	start := len(dst)
	vw.reset(dst)
	vw.push(mElement)
	err := c.CopyValue(vw, src)
	if err != nil {
		return 0, dst, err
	}
	return bsontype.Type(vw.buf[start]), vw.buf[start+2:], nil
}
AppendValueBytes functions the same as CopyValueToBytes, but will append the
result to dst.
package bsonrw
import (
	"fmt"
	"io"
	"go.mongodb.org/mongo-driver/bson/bsontype"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
type Copier struct{}
func NewCopier() Copier {
	return Copier{}
}
func CopyDocument(dst ValueWriter, src ValueReader) error {
	return Copier{}.CopyDocument(dst, src)
}
func (c Copier) CopyDocument(dst ValueWriter, src ValueReader) error {
	dr, err := src.ReadDocument()
	if err != nil {
		return err
	}
	dw, err := dst.WriteDocument()
	if err != nil {
		return err
	}
	return c.copyDocumentCore(dw, dr)
}
func (c Copier) CopyArrayFromBytes(dst ValueWriter, src []byte) error {
	aw, err := dst.WriteArray()
	if err != nil {
		return err
	}
	err = c.CopyBytesToArrayWriter(aw, src)
	if err != nil {
		return err
	}
	return aw.WriteArrayEnd()
}
func (c Copier) CopyDocumentFromBytes(dst ValueWriter, src []byte) error {
	dw, err := dst.WriteDocument()
	if err != nil {
		return err
	}
	err = c.CopyBytesToDocumentWriter(dw, src)
	if err != nil {
		return err
	}
	return dw.WriteDocumentEnd()
}
type writeElementFn func(key string) (ValueWriter, error)
func (c Copier) CopyBytesToArrayWriter(dst ArrayWriter, src []byte) error {
	wef := func(_ string) (ValueWriter, error) {
		return dst.WriteArrayElement()
	}
	return c.copyBytesToValueWriter(src, wef)
}
func (c Copier) CopyBytesToDocumentWriter(dst DocumentWriter, src []byte) error {
	wef := func(key string) (ValueWriter, error) {
		return dst.WriteDocumentElement(key)
	}
	return c.copyBytesToValueWriter(src, wef)
}
func (c Copier) copyBytesToValueWriter(src []byte, wef writeElementFn) error {
	length, rem, ok := bsoncore.ReadLength(src)
	if !ok {
		return fmt.Errorf("couldn't read length from src, not enough bytes. length=%d", len(src))
	}
	if len(src) < int(length) {
		return fmt.Errorf("length read exceeds number of bytes available. length=%d bytes=%d", len(src), length)
	}
	rem = rem[:length-4]
	var t bsontype.Type
	var key string
	var val bsoncore.Value
	for {
		t, rem, ok = bsoncore.ReadType(rem)
		if !ok {
			return io.EOF
		}
		if t == bsontype.Type(0) {
			if len(rem) != 0 {
				return fmt.Errorf("document end byte found before end of document. remaining bytes=%v", rem)
			}
			break
		}
		key, rem, ok = bsoncore.ReadKey(rem)
		if !ok {
			return fmt.Errorf("invalid key found. remaining bytes=%v", rem)
		}
		vw, err := wef(key)
		if err != nil {
			return err
		}
		val, rem, ok = bsoncore.ReadValue(rem, t)
		if !ok {
			return fmt.Errorf("not enough bytes available to read type. bytes=%d type=%s", len(rem), t)
		}
		err = c.CopyValueFromBytes(vw, t, val.Data)
		if err != nil {
			return err
		}
	}
	return nil
}
func (c Copier) CopyDocumentToBytes(src ValueReader) ([]byte, error) {
	return c.AppendDocumentBytes(nil, src)
}
func (c Copier) AppendDocumentBytes(dst []byte, src ValueReader) ([]byte, error) {
	if br, ok := src.(BytesReader); ok {
		_, dst, err := br.ReadValueBytes(dst)
		return dst, err
	}
	vw := vwPool.Get().(*valueWriter)
	defer vwPool.Put(vw)
	vw.reset(dst)
	err := c.CopyDocument(vw, src)
	dst = vw.buf
	return dst, err
}
func (c Copier) AppendArrayBytes(dst []byte, src ValueReader) ([]byte, error) {
	if br, ok := src.(BytesReader); ok {
		_, dst, err := br.ReadValueBytes(dst)
		return dst, err
	}
	vw := vwPool.Get().(*valueWriter)
	defer vwPool.Put(vw)
	vw.reset(dst)
	err := c.copyArray(vw, src)
	dst = vw.buf
	return dst, err
}
func (c Copier) CopyValueFromBytes(dst ValueWriter, t bsontype.Type, src []byte) error {
	if wvb, ok := dst.(BytesWriter); ok {
		return wvb.WriteValueBytes(t, src)
	}
	vr := vrPool.Get().(*valueReader)
	defer vrPool.Put(vr)
	vr.reset(src)
	vr.pushElement(t)
	return c.CopyValue(dst, vr)
}
func (c Copier) CopyValueToBytes(src ValueReader) (bsontype.Type, []byte, error) {
	return c.AppendValueBytes(nil, src)
}