GetBSON method for individual elements [Go + mgo]

962 views Asked by At

In Go, I get the json marshalling/unmarshalling. If a struct or type has a MarshalJSON method, when calling json.Marshal on another struct which has the former as a field, that structs's MarshalJSON method will be called. So from what I gather and have seen in practice...

  1. type MyType struct has a MarshalJSON method to marshal itself a string.
  2. type MyDocument struct has MyType as a field.
  3. When calling json.Marshal() on MyDocument, the MyType field will be marshalled as a string due to it implementing json.Marshaller.

I'm trying to make my system database-agnostic and am implementing a service for MongoDB using the mgo driver, which means implementing bson.Getter and bson.Setter on all structs and things I want marshalled in a specific way. This is where it gets confusing.

Because Go doesn't have native fixed-point arithmetic, I'm using Shopspring's decimal package (found here) to deal with currency values. Decimal marshals to JSON perfectly but I have a named type type Currency decimal.Decimal which I just can't get to marshal down to BSON.

These are my implementations which convert the decimal to a float64 and try marshalling that in the same way I've done for json:

/*
Implements the bson.Getter interface.
*/
func (c Currency) GetBSON() (interface{}, error) {
    f, _ := decimal.Decimal(c).Float64()
    return f, nil
}

/*
Implements the bson.Setter interface.
*/
func (c *Currency) SetBSON(raw bson.Raw) error {
    var f float64
    e := raw.Unmarshal(&f)
    if e == nil {
        *c = Currency(decimal.NewFromFloat(f))
    }
    return e
}

Only problem is in the documentation for the bson package:

Marshal serializes the in value, which may be a map or a struct value.

Because it's not a struct or a map it just produces an empty document.

I'm just trying to marshal one bit of data which will only need to be marshalled as part of larger structs, but the package will only let me do it on whole documents. What should I do to get the results I need?

0

There are 0 answers