package wmo import ( "context" "go.mongodb.org/mongo-driver/bson" "gogs.mikescher.com/BlackForestBytes/goext/exerr" ) func (c *Coll[TData]) decodeSingle(ctx context.Context, dec Decodable) (TData, error) { var res TData var err error if c.customDecoder != nil { res, err = (*c.customDecoder)(ctx, dec) if err != nil { return *new(TData), exerr.Wrap(err, "failed to decode single entity with custom-decoder").Type("decoder", *c.customDecoder).Build() } } else { err = dec.Decode(&res) if err != nil { return *new(TData), exerr.Wrap(err, "failed to decode single entity").Type("target-type", res).Build() } } for _, hook := range c.unmarshalHooks { res = hook(res) } return res, nil } func (c *Coll[TData]) decodeAll(ctx context.Context, cursor Cursorable) ([]TData, error) { res := make([]TData, 0, cursor.RemainingBatchLength()) if c.customDecoder != nil { for cursor.Next(ctx) { entry, err := (*c.customDecoder)(ctx, cursor) if err != nil { return nil, exerr.Wrap(err, "failed to decode entity with custom-decoder").Type("decoder", *c.customDecoder).Build() } res = append(res, entry) } } else { err := cursor.All(ctx, &res) if err != nil { return nil, exerr.Wrap(err, "failed to batch-decode entity").Type("target-type", res).Build() } } for i := 0; i < len(res); i++ { for _, hook := range c.unmarshalHooks { res[i] = hook(res[i]) } } return res, nil } func (c *Coll[TData]) decodeSingleOrRequery(ctx context.Context, dec Decodable) (TData, error) { if c.extraModPipeline == nil { // simple case, we can just decode the result and return it return c.decodeSingle(ctx, dec) } else { // annyoing case, we have a extraModPipeline and need to re-query the document such that the extraModPipeline is applied... type genDoc struct { ID any `bson:"_id"` } var res genDoc err := dec.Decode(&res) if err != nil { return *new(TData), exerr.Wrap(err, "failed to ID-decode entity").Build() } v, err := c.findOneInternal(ctx, bson.M{"_id": res.ID}, false) if err != nil { return *new(TData), exerr.Wrap(err, "failed to re-query entity").Any("_id", res.ID).Build() } return *v, nil } }