Using gopkg.in/mgo.v2/bson
, I wonder how to marshal an interface{} value into a value of type bson.Raw
.
The documentation for bson.Raw
states:
Using this type it is possible to unmarshal or marshal values partially.
But I can't find a Marshal function that would return bson.Raw
.
What am I missing?
Example of what I try to do:
package main
import (
"fmt"
"gopkg.in/mgo.v2/bson"
)
func main() {
// How to avoid a MarshalRaw help function?
raw, err := MarshalRaw("Hello world")
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", raw)
}
func MarshalRaw(v interface{}) (*bson.Raw, error) {
bin, err := bson.Marshal(struct{ Raw interface{} }{v})
if err != nil {
return nil, err
}
var raw struct{ Raw bson.Raw }
err = bson.Unmarshal(bin, &raw)
if err != nil {
return nil, err
}
return &raw.Raw, nil
}
Output:
&{Kind:2 Data:[12 0 0 0 72 101 108 108 111 32 119 111 114 108 100 0]}
bson.Raw is used as a value both when marshaling and unmarshaling.
To transform an interface{}
into a bson.Raw
, the first thing to do is to marshal it so that you get the plain document data that represents whatever is being marshaled:
var value interface{} = bson.M{"some": "value"}
data, err := bson.Marshal(value)
if err != nil {
log.Fatal(err)
}
and then it may have one or more fields unmarshaled into bson.Raw
values:
var doc struct{ Some bson.Raw }
err = bson.Unmarshal(data, &doc)
if err != nil {
log.Fatal(err)
}
or even the entire document:
var doc bson.Raw
err = bson.Unmarshal(data, &doc)
if err != nil {
log.Fatal(err)
}
If you want the entire document rather than just a field, you can also use this shortcut:
doc := bson.Raw{3, data}
The 3 constant represents a document in the bson specification, and it must of course match the provided data. Since BSON only supports documents at the top level, we know this must be correct.