Wilbert
Wilbert

Reputation: 7399

Golang JSON Serialization/Deserialization

I have a struct as follows:

type Node struct {
    Name     string
    Children []*Node
    Values   []string
}

I also have a set of json files describing my trees such as:

{
  "something": {
    "someblah": [
      "fluf",
      "glah"
    ],
    "someother": {
      "someotter": [
        "blib",
        "fnar"
      ]
    }
  }
}

How can I deserialize these files into the structs?

All the examples I found seem to require a different structure with named key/value pairs.

For this, the structure is key:

I cannot understand how to map this logic into the golang json serializer.

Upvotes: 0

Views: 4145

Answers (1)

Thundercat
Thundercat

Reputation: 120951

The easiest approach is to decode to map[string]interface{} and convert that to the desired structure:

var m map[string]interface{}
err := json.Unmarshal(data, &m)
if err != nil {
    // handle error
}
node := convert(m, "")

...

func convert(name string, m map[string]interface{}) *Node {
    n := Node{Name: name}
    for k, v := range m {
        switch v := v.(type) {
        case []interface{}:
            nn := Node{Name: k}
            for _, e := range v {
                s, ok := e.(string)
                if !ok {
                    panic(fmt.Sprintf("expected string, got %T", e))
                }
                nn.Values = append(nn.Values, s)
            }
            n.Children = append(n.Children, &nn)
        case map[string]interface{}:
            n.Children = append(n.Children, convert(k, v))
        default:
            panic("unexpected type")
        }
    }
    return &n
}

The convert function panics when it encounters a value of an unexpected type. Depending on the requirements of your application, you may want to ignore these values or return an error.

Run it on the playground.

Upvotes: 4

Related Questions