func (d *MDoc) UnmarshalBSON(b []byte) error {
	if d == nil {
		return ErrNilDocument
	}
	if err := bsoncore.Document(b).Validate(); err != nil {
		return err
	}
	elems, err := bsoncore.Document(b).Elements()
	if err != nil {
		return err
	}
	var val Val
	for _, elem := range elems {
		rawv := elem.Value()
		err = val.UnmarshalBSONValue(rawv.Type, rawv.Data)
		if err != nil {
			return err
		}
		(*d)[elem.Key()] = val
	}
	return nil
}
UnmarshalBSON implements the Unmarshaler interface.
package bsonx
import (
	"bytes"
	"fmt"
	"go.mongodb.org/mongo-driver/bson/bsontype"
	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
type MDoc map[string]Val
func ReadMDoc(b []byte) (MDoc, error) {
	doc := make(MDoc, 0)
	err := doc.UnmarshalBSON(b)
	if err != nil {
		return nil, err
	}
	return doc, nil
}
func (d MDoc) Copy() MDoc {
	d2 := make(MDoc, len(d))
	for k, v := range d {
		d2[k] = v
	}
	return d2
}
func (d MDoc) Lookup(key ...string) Val {
	val, _ := d.LookupErr(key...)
	return val
}
func (d MDoc) LookupErr(key ...string) (Val, error) {
	elem, err := d.LookupElementErr(key...)
	return elem.Value, err
}
func (d MDoc) LookupElement(key ...string) Elem {
	elem, _ := d.LookupElementErr(key...)
	return elem
}
func (d MDoc) LookupElementErr(key ...string) (Elem, error) {
	if len(key) == 0 {
		return Elem{}, KeyNotFound{Key: key}
	}
	var elem Elem
	var err error
	val, ok := d[key[0]]
	if !ok {
		return Elem{}, KeyNotFound{Key: key}
	}
	if len(key) == 1 {
		return Elem{Key: key[0], Value: val}, nil
	}
	switch val.Type() {
	case bsontype.EmbeddedDocument:
		switch tt := val.primitive.(type) {
		case Doc:
			elem, err = tt.LookupElementErr(key[1:]...)
		case MDoc:
			elem, err = tt.LookupElementErr(key[1:]...)
		}
	default:
		return Elem{}, KeyNotFound{Type: val.Type()}
	}
	switch tt := err.(type) {
	case KeyNotFound:
		tt.Depth++
		tt.Key = key
		return Elem{}, tt
	case nil:
		return elem, nil
	default:
		return Elem{}, err  
	}
}
func (d MDoc) MarshalBSONValue() (bsontype.Type, []byte, error) {
	if d == nil {
		return bsontype.Null, nil, nil
	}
	data, _ := d.MarshalBSON()
	return bsontype.EmbeddedDocument, data, nil
}
func (d MDoc) MarshalBSON() ([]byte, error) { return d.AppendMarshalBSON(nil) }
func (d MDoc) AppendMarshalBSON(dst []byte) ([]byte, error) {
	idx, dst := bsoncore.ReserveLength(dst)
	for k, v := range d {
		t, data, _ := v.MarshalBSONValue()  
		dst = append(dst, byte(t))
		dst = append(dst, k...)
		dst = append(dst, 0x00)
		dst = append(dst, data...)
	}
	dst = append(dst, 0x00)
	dst = bsoncore.UpdateLength(dst, idx, int32(len(dst[idx:])))
	return dst, nil
}