Skip to content

Instantly share code, notes, and snippets.

@jriquelme
Last active March 14, 2018 01:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jriquelme/91100644bb4a6e47b77f0053ed34820f to your computer and use it in GitHub Desktop.
Save jriquelme/91100644bb4a6e47b77f0053ed34820f to your computer and use it in GitHub Desktop.
Custom UnmarshalJSON implementation to support a single property with string/object values
package main
import (
"encoding/json"
)
type Business struct {
ID string `json:"id"`
Name string `json:"name"`
}
type BusinessRef struct {
Business
IDOnly bool
}
func (bj *BusinessRef) UnmarshalJSON(data []byte) error {
var id string
err := json.Unmarshal(data, &id)
if err != nil {
// if the err was because the value found is an object,
// try again with the Business struct
typeErr, ok := err.(*json.UnmarshalTypeError)
if ok && typeErr.Value == "object" {
return json.Unmarshal(data, &bj.Business)
}
// otherwise, return the original error
return err
}
bj.ID = id
bj.IDOnly = true // indicate that business was just a string
return nil
}
type JobOffer struct {
Business *BusinessRef `json:"business"`
Position string `json:"position"`
}
package main
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
)
func TestBusinessRef_UnmarshalJSON(t *testing.T) {
t.Parallel()
data := []byte(`{
"business": "76261649-1",
"position": "Software Developer"
}`)
var jobOffer JobOffer
err := json.Unmarshal(data, &jobOffer)
assert.Nil(t, err)
assert.Equal(t, "76261649-1", jobOffer.Business.ID)
assert.True(t, jobOffer.Business.IDOnly)
assert.Equal(t, "Software Developer", jobOffer.Position)
}
func TestBusinessRef_UnmarshalJSON2(t *testing.T) {
t.Parallel()
data := []byte(`{
"business":{
"id": "76261649-1",
"name": "Larix Sistemas Informáticos Limitada"
},
"position": "Software Developer"
}`)
var jobOffer JobOffer
err := json.Unmarshal(data, &jobOffer)
assert.Nil(t, err)
assert.Equal(t, "76261649-1", jobOffer.Business.ID)
assert.Equal(t, "Larix Sistemas Informáticos Limitada", jobOffer.Business.Name)
assert.False(t, jobOffer.Business.IDOnly)
assert.Equal(t, "Software Developer", jobOffer.Position)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment