Why won't mgo unmarshall my struct properly?

1.3k views Asked by At

Earlier I posted this question asking about writing custom BSON marshalling/unmarshalling in Go using mgo. Now I've come to test it I think I've hit on a bigger problem. All my structs unmarshal to nil values.

This is my currency struct with the implementations of bson.Getter and bson.Setter:

type Currency struct {
    value        decimal.Decimal //The actual value of the currency.
    currencyCode string          //The ISO currency code.
}

/*
GetBSON implements bson.Getter.
*/
func (c Currency) GetBSON() (interface{}, error) {
    f, _ := c.Value().Float64()
    return bson.Marshal(struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    }{
        Value:        f,
        CurrencyCode: c.currencyCode,
    })
}

/*
SetBSON implements bson.Setter.
*/
func (c *Currency) SetBSON(raw bson.Raw) error {
    decoded := new(struct {
        Value        float64 `json:"value" bson:"value"`
        CurrencyCode string  `json:"currencyCode" bson:"currencyCode"`
    })

    fmt.Println(string(raw.Data))
    bsonErr := raw.Unmarshal(decoded)

    if bsonErr == nil {
        fmt.Println("Debug: no error returned.")
        fmt.Println(decoded)
        c.value = decimal.NewFromFloat(decoded.Value)
        c.currencyCode = decoded.CurrencyCode
        return nil
    } else {
        return bsonErr
    }
}

By looking at the raw data, it marshals correctly, but when unmarshaling the resulting struct is just empty. Any ideas where I'm going wrong here? I used the go get gopkg.in/mgo.v2command literally yesterday so I would hope it was up to date and a bug like this wouldn't be present in "the hottest MongoDB driver around".

1

There are 1 answers

2
Gustavo Niemeyer On BEST ANSWER

The GetBSON method should return the value to be marshaled, not the binary data resulting from marshaling it. That's why its first result type is interface{} and not []byte.