gojson-rpc

How to parse JSON-RPC table with different type


I want get informations in JSON-RPC file with this structure :

{
    "id": "foo1",
    "error": null,
    "result": [
        {
            "key": [
                "hello 1",
                1,
                "world 1"
            ],
            "val": {
                "type": "static"
            }
        },
        {
            "key": [
                "hello 2",
                1,
                "world 2"
            ],
            "val": {
                "type": "static"
            }
        }
    ]
}

This is my parsing function, Key is string table (can't accept int type) :

type JsonRpcRsp struct {
    Id     string          `json:"id"`
    Error  *string         `json:"error"`
    Result json.RawMessage `json:"result"`
}

type JsonRpcEntry_Val struct {
    Type     string          `json:"type"`
}
type JsonRpcEntry struct {
    Key     [3]string          `json:"key"`
    Val     JsonRpcEntry_Val  `json:"val"`
}

jsonResult := JsonRpcRsp{}
json.Unmarshal(data, &jsonResult)
entries := []JsonRpcEntry{}
for _, val := range jsonResult {
    json.Unmarshal(val.Result, &entries)
}

How to parse "key" table ?... problem is there are different types

key table structure is :

[ <string>, <int>, <string>]

Solution

  • To unmarshal arrays of different types in Go you'll need to use interfaces and consequently type assertions if you need access to the types.

    This will work for you:

    type Result struct {
        Key [3]interface{} `json:"key"`
        Val struct {
            Type string `json:"type"`
        } `json:"val"`
    }
    
    msg := JsonRpcRsp{}
    json.Unmarshal(data, &msg)
    
    var result []Result
    json.Unmarshal(msg.Result, &result)
    
    for _, v := range result {
        key1 := v.Key[0].(string)
        key2 := v.Key[1].(float64)
        key3 := v.Key[2].(string)
    
        fmt.Println(key1, key2, key3)
    }
    

    After asserting the three interfaces to their types, you can then work with them further, depending on your use case.