Uploaded image for project: 'Go Driver'
  1. Go Driver
  2. GODRIVER-890

Error on Marshal method of a struct

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 1.0.0
    • Component/s: BSON
    • None
    • Environment:
      Linux Ubuntu 16.4

      I've made some tests implementing the `Marshaler` and `ValueMarshaler` interfaces, but any of then I was able to make it work. I always get a error similar to this:

      (mongo.MarshalError) cannot transform type map[string]interface {} to a BSON Document: WriteString can only write while positioned on a Element or Value but is positioned on a TopLevel

       
      I wrote a test which points exactly to the problem:

      package main
      
      import (
      	"context"
      	"time"
      
      	"github.com/davecgh/go-spew/spew"
      
      	"go.mongodb.org/mongo-driver/bson"
      	"go.mongodb.org/mongo-driver/bson/bsontype"
      	"go.mongodb.org/mongo-driver/mongo"
      	"go.mongodb.org/mongo-driver/mongo/options"
      )
      
      var (
      	client   *mongo.Client
      	database *mongo.Database
      	ctx      context.Context
      )
      
      type MyValue struct {
      }
      
      func (m MyValue) MarshalBSONValue() (bsontype.Type, []byte, error) {
      	b, err := bson.Marshal(`fixed value`)
      	if err != nil {
      		return bsontype.String, nil, err
      	}
      
      	return bsontype.String, b, err
      }
      
      // func (m MyValue) MarshalBSONValue() (bsontype.Type, []byte, error) {
      // 	return bsontype.String, []byte(`fixed value`), nil
      // }
      
      type MyOtherValue struct {
      }
      
      func (m MyOtherValue) MarshalBSON() ([]byte, error) {
      	return bson.Marshal(`fixed value`)
      }
      
      // func (m MyOtherValue) MarshalBSON() ([]byte, error) {
      // 	return []byte(`fixed value`), nil
      // }
      
      func main() {
      	defer disconnect()
      
      	connect()
      
      	insert()
      }
      
      func insert() {
      	test1 := map[string]interface{}{
      		"value1": "test 1",
      		"value2": MyValue{},
      		"value3": MyOtherValue{},
      	}
      
      	res, err := database.Collection("encoding").InsertOne(ctx, test1)
      
      	spew.Dump(res, err)
      }
      
      func read() {
      	response := map[string]interface{}{}
      
      	res := database.Collection("encoding").FindOne(ctx, bson.M{})
      	res.Decode(&response)
      
      	spew.Dump(response)
      }
      
      func connect() {
      	var err error
      
      	ctx, _ = context.WithTimeout(context.Background(), 30*time.Second)
      	clientOptions := []*options.ClientOptions{
      		options.Client().ApplyURI("localhost:27017"),
      	}
      
      	client, err = mongo.Connect(ctx, clientOptions...)
      	if nil != err {
      		panic(err)
      	}
      
      	database = client.Database("test")
      }
      
      func disconnect() {
      	if client != nil {
      		client.Disconnect(ctx)
      	}
      }
      

      Is there any problem with my implementation or is actually a bug?

            Assignee:
            kris.brandow@mongodb.com Kristofer Brandow (Inactive)
            Reporter:
            souzasrafael Rafael Souza
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: