Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Unmarshal JSON?

Tags:

json

go

I am trying to unmarshal JSON into a struct. However, the struct has a field with a tag. Using reflection, and I try to see if the tag has the string "json" in it. If it does, then the json to unmarshal should simply be unmarshaled into the field as a string.

Example:

const data = `{"I":3, "S":{"phone": {"sales": "2223334444"}}}`
type A struct {
    I int64
    S string `sql:"type:json"`
}

Problem is simple - unmarshal "S" in the json as a string into the struct A.

This is how far I have come. But I am stuck here.

http://play.golang.org/p/YzrhjuXxGN

like image 259
sat Avatar asked May 22 '14 05:05

sat


1 Answers

This is the go way of doing it - no reflection requred. Create a new type RawString and create MarshalJSON and UnmarshalJSON methods for it. (playground)

// RawString is a raw encoded JSON object.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawString string

// MarshalJSON returns *m as the JSON encoding of m.
func (m *RawString) MarshalJSON() ([]byte, error) {
    return []byte(*m), nil
}

// UnmarshalJSON sets *m to a copy of data.
func (m *RawString) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("RawString: UnmarshalJSON on nil pointer")
    }
    *m += RawString(data)
    return nil
}

const data = `{"i":3, "S":{"phone": {"sales": "2223334444"}}}`

type A struct {
    I int64
    S RawString `sql:"type:json"`
}

func main() {
    a := A{}
    err := json.Unmarshal([]byte(data), &a)
    if err != nil {
        log.Fatal("Unmarshal failed", err)
    }
    fmt.Println("Done", a)
}

I modified the implementation of RawMessage to create the above.

like image 96
Nick Craig-Wood Avatar answered Sep 23 '22 00:09

Nick Craig-Wood