Why won't mgo unmarshall my struct properly?
Asked Answered
S

1

1

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".

Sumerian answered 17/6, 2015 at 15:23 Comment(1)
your getter and setter not symmetrical. is GetBSON returns a []byte, SetBSON need unmarshal a []byte type, and do a unmarshal again to convert []byte to struct.Advise
B
4

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.

Boomerang answered 17/6, 2015 at 16:18 Comment(2)
Muchas gracias :) I got rid of the bson.Marshal around the return struct and it instantly worked.Sumerian
Hi, How can I achieve the same thing using this driver? go.mongodb.org/mongo-driver/mongoDrama

© 2022 - 2024 — McMap. All rights reserved.