title: Custom marshalling to bson and JSON (Golang & mgo)
body: <p>I have the following type in Golang:</p>
  
  <p><code>type Base64Data []byte</code></p>
  
  <p>In order to support unmarshalling a base64 encoded string to this type, I did the following:</p>
  
  <pre><code>func (b *Base64Data) UnmarshalJSON(data []byte) error {
      if len(data) == 0 {
          return nil
      }
  
      content, err := base64.StdEncoding.DecodeString(string(data[1 : len(data)-1]))
      if err != nil {
          return err
      }
  
      *b = []byte(xml)
      return nil
  }
  </code></pre>
  
  <p>Now I also want to be able to marshal and unmarshal it to mongo database, using mgo Golang library.
  The problem is that I already have documents there stored as base64 encoded string, so I have to maintain that.
  I tried to do the following:</p>
  
  <pre><code>func (b Base64Data) GetBSON() (interface{}, error) {
      return base64.StdEncoding.EncodeToString([]byte(b)), nil
  }
  
  func (b *Base64DecodedXml) SetBSON(raw bson.Raw) error {
      var s string
      var err error
      if err = raw.Unmarshal(&amp;s); err != nil {
          return err
      }
      *b, err = base64.StdEncoding.DecodeString(s)
      return err
  }
  </code></pre>
  
  <p>So that after unmarshaling, the data is already decoded, so I need to encode it back, and return it as a string so it will be written to db as a string (and vice versa)
  For that I implemented bson getter and setter, but it seems only the getter is working properly</p>
  
  <p>JSON unmarshaling from base64 encoded string works, as well marshaling it to database. but unmarshling setter seems to not be called at all.</p>
  
  <p>Can anyone suggest what I'm missing, so that I'll be able to properly hold the data decoded in memory, but encoded string type?</p>
  
  <p>This is a test I tried to run:</p>
  
  <pre><code>b := struct {
      Value shared.Base64Data `json:"value" bson:"value"`
  }{}
  s := `{"value": "PHJvb3Q+aGVsbG88L3Jvb3Q+"}`
  require.NoError(t, json.Unmarshal([]byte(s), &amp;b))
  t.Logf("%v", string(b.Value))
  b4, err := bson.Marshal(b)
  require.NoError(t, err)
  t.Logf("%v", string(b4))
  require.NoError(t, bson.Unmarshal(b4, &amp;b))
  t.Logf("%v", string(b.Value))
  </code></pre>