func (r *SingleResult) DecodeBytes() (bson.Raw, error) {
	raw, err := r.res.DecodeBytes()
	return raw, xo.W(err)
}
DecodeBytes will return the raw document bytes.s
package coal
import (
	"context"
	"errors"
	"reflect"
	"github.com/256dpi/lungo"
	"github.com/256dpi/xo"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)
func IsMissing(err error) bool {
	return err == lungo.ErrNoDocuments || errors.Is(err, lungo.ErrNoDocuments)
}
func IsDuplicate(err error) bool {
	return lungo.IsUniquenessError(err)
}
type Collection struct {
	coll lungo.ICollection
}
func (c *Collection) Native() lungo.ICollection {
	return c.coll
}
func (c *Collection) Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (*Iterator, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.Aggregate")
	span.Tag("collection", c.coll.Name())
	csr, err := c.coll.Aggregate(ctx, pipeline, opts...)
	if err != nil {
		span.End()
		return nil, xo.W(err)
	}
	iterator := newIterator(ctx, csr, span)
	return iterator, nil
}
func (c *Collection) BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...*options.BulkWriteOptions) (*mongo.BulkWriteResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.BulkWrite")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.BulkWrite(ctx, models, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("inserted", res.InsertedCount)
	span.Tag("matched", res.MatchedCount)
	span.Tag("modified", res.ModifiedCount)
	span.Tag("deleted", res.DeletedCount)
	span.Tag("upserted", res.UpsertedCount)
	return res, nil
}
func (c *Collection) CountDocuments(ctx context.Context, filter interface{}, opts ...*options.CountOptions) (int64, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.CountDocuments")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	count, err := c.coll.CountDocuments(ctx, filter, opts...)
	if err != nil {
		return 0, xo.W(err)
	}
	span.Tag("count", count)
	return count, nil
}
func (c *Collection) DeleteMany(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.DeleteMany")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.DeleteMany(ctx, filter, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("deleted", res.DeletedCount)
	return res, nil
}
func (c *Collection) DeleteOne(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.DeleteOne")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.DeleteOne(ctx, filter, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("deleted", res.DeletedCount == 1)
	return res, nil
}
func (c *Collection) Distinct(ctx context.Context, field string, filter interface{}, opts ...*options.DistinctOptions) ([]interface{}, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.Distinct")
	span.Tag("collection", c.coll.Name())
	span.Tag("field", field)
	defer span.End()
	list, err := c.coll.Distinct(ctx, field, filter, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("length", len(list))
	return list, nil
}
func (c *Collection) EstimatedDocumentCount(ctx context.Context, opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.EstimatedDocumentCount")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	count, err := c.coll.EstimatedDocumentCount(ctx, opts...)
	if err != nil {
		return 0, xo.W(err)
	}
	span.Tag("count", count)
	return count, nil
}
func (c *Collection) Find(ctx context.Context, filter interface{}, opts ...*options.FindOptions) (*Iterator, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.Find")
	span.Tag("collection", c.coll.Name())
	csr, err := c.coll.Find(ctx, filter, opts...)
	if err != nil {
		span.End()
		return nil, xo.W(err)
	}
	iterator := newIterator(ctx, csr, span)
	return iterator, nil
}
func (c *Collection) FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) lungo.ISingleResult {
	ctx, span := xo.Trace(ctx, "coal/Collection.FindOne")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res := c.coll.FindOne(ctx, filter, opts...)
	return &SingleResult{res: res}
}
func (c *Collection) FindOneAndDelete(ctx context.Context, filter interface{}, opts ...*options.FindOneAndDeleteOptions) lungo.ISingleResult {
	ctx, span := xo.Trace(ctx, "coal/Collection.FindOneAndDelete")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res := c.coll.FindOneAndDelete(ctx, filter, opts...)
	return &SingleResult{res: res}
}
func (c *Collection) FindOneAndReplace(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.FindOneAndReplaceOptions) lungo.ISingleResult {
	ctx, span := xo.Trace(ctx, "coal/Collection.FindOneAndReplace")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res := c.coll.FindOneAndReplace(ctx, filter, replacement, opts...)
	return &SingleResult{res: res}
}
func (c *Collection) FindOneAndUpdate(ctx context.Context, filter interface{}, update interface{}, opts ...*options.FindOneAndUpdateOptions) lungo.ISingleResult {
	ctx, span := xo.Trace(ctx, "coal/Collection.FindOneAndUpdate")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res := c.coll.FindOneAndUpdate(ctx, filter, update, opts...)
	return &SingleResult{res: res}
}
func (c *Collection) InsertMany(ctx context.Context, documents []interface{}, opts ...*options.InsertManyOptions) (*mongo.InsertManyResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.InsertMany")
	span.Tag("collection", c.coll.Name())
	span.Tag("count", len(documents))
	defer span.End()
	res, err := c.coll.InsertMany(ctx, documents, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	return res, nil
}
func (c *Collection) InsertOne(ctx context.Context, document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.InsertOne")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.InsertOne(ctx, document, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	return res, nil
}
func (c *Collection) ReplaceOne(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.ReplaceOptions) (*mongo.UpdateResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.ReplaceOne")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.ReplaceOne(ctx, filter, replacement, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	return res, nil
}
func (c *Collection) UpdateMany(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.UpdateMany")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.UpdateMany(ctx, filter, update, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("matched", res.MatchedCount)
	span.Tag("modified", res.ModifiedCount)
	span.Tag("upserted", res.UpsertedCount)
	return res, nil
}
func (c *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
	ctx, span := xo.Trace(ctx, "coal/Collection.UpdateOne")
	span.Tag("collection", c.coll.Name())
	defer span.End()
	res, err := c.coll.UpdateOne(ctx, filter, update, opts...)
	if err != nil {
		return nil, xo.W(err)
	}
	span.Tag("matched", res.MatchedCount == 1)
	span.Tag("modified", res.ModifiedCount == 1)
	span.Tag("upserted", res.UpsertedCount == 1)
	return res, nil
}
type Iterator struct {
	ctx     context.Context
	cursor  lungo.ICursor
	spans   []xo.Span
	counter int64
	error   error
}
func newIterator(ctx context.Context, cursor lungo.ICursor, span xo.Span) *Iterator {
	return &Iterator{
		ctx:    ctx,
		cursor: cursor,
		spans:  []xo.Span{span},
	}
}
func (i *Iterator) All(list interface{}) error {
	length := int64(reflect.ValueOf(list).Elem().Len())
	err := i.cursor.All(i.ctx, list)
	i.counter = int64(reflect.ValueOf(list).Elem().Len()) - length
	for _, span := range i.spans {
		span.Tag("loaded", i.counter)
		span.End()
	}
	return xo.W(err)
}
func (i *Iterator) Next() bool {
	if i.error != nil {
		return false
	}
	if !i.cursor.Next(i.ctx) {
		i.error = i.cursor.Err()
		i.Close()
		return false
	}
	i.counter++
	return true
}
func (i *Iterator) Decode(v interface{}) error {
	return xo.W(i.cursor.Decode(v))
}
func (i *Iterator) Error() error {
	return xo.W(i.error)
}
func (i *Iterator) Close() {
	if i.cursor != nil {
		_ = i.cursor.Close(i.ctx)
	}
	for _, span := range i.spans {
		span.Tag("loaded", i.counter)
		span.End()
	}
	i.spans = nil
}
type SingleResult struct {
	res lungo.ISingleResult
}
func (r *SingleResult) Decode(i interface{}) error {
	return xo.W(r.res.Decode(i))
}