...

Source file src/go.mongodb.org/mongo-driver/internal/codecutil/encoding.go

Documentation: go.mongodb.org/mongo-driver/internal/codecutil

     1  // Copyright (C) MongoDB, Inc. 2023-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package codecutil
     8  
     9  import (
    10  	"bytes"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  	"reflect"
    15  
    16  	"go.mongodb.org/mongo-driver/bson"
    17  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
    18  )
    19  
    20  var ErrNilValue = errors.New("value is nil")
    21  
    22  // MarshalError is returned when attempting to transform a value into a document
    23  // results in an error.
    24  type MarshalError struct {
    25  	Value interface{}
    26  	Err   error
    27  }
    28  
    29  // Error implements the error interface.
    30  func (e MarshalError) Error() string {
    31  	return fmt.Sprintf("cannot transform type %s to a BSON Document: %v",
    32  		reflect.TypeOf(e.Value), e.Err)
    33  }
    34  
    35  // EncoderFn is used to functionally construct an encoder for marshaling values.
    36  type EncoderFn func(io.Writer) (*bson.Encoder, error)
    37  
    38  // MarshalValue will attempt to encode the value with the encoder returned by
    39  // the encoder function.
    40  func MarshalValue(val interface{}, encFn EncoderFn) (bsoncore.Value, error) {
    41  	// If the val is already a bsoncore.Value, then do nothing.
    42  	if bval, ok := val.(bsoncore.Value); ok {
    43  		return bval, nil
    44  	}
    45  
    46  	if val == nil {
    47  		return bsoncore.Value{}, ErrNilValue
    48  	}
    49  
    50  	buf := new(bytes.Buffer)
    51  
    52  	enc, err := encFn(buf)
    53  	if err != nil {
    54  		return bsoncore.Value{}, err
    55  	}
    56  
    57  	// Encode the value in a single-element document with an empty key. Use
    58  	// bsoncore to extract the first element and return the BSON value.
    59  	err = enc.Encode(bson.D{{Key: "", Value: val}})
    60  	if err != nil {
    61  		return bsoncore.Value{}, MarshalError{Value: val, Err: err}
    62  	}
    63  
    64  	return bsoncore.Document(buf.Bytes()).Index(0).Value(), nil
    65  }
    66  

View as plain text