I'm teaching myself how to use the JSON package in Golang. It seems straightforward for a lot of things, but I'm having troubles parsing some JSON data I retrieved from my 3D printer. The JSON looks like this:
{
"tasks": [
{
"class": "Task",
"id": "5fee231a",
"instances": {
"28253266": {
"class": "StateInstance",
"id": "28253266",
"progress": 1,
"stateType": "Y-EdgeAvoiding"
},
"1d774b49": {
"class": "StateInstance",
"id": "1d774b49",
"progress": 1,
"stateType": "X-Calibration"
},
},
"stateType": "StartingUp"
}
]
}
(NB: There's a few more "instances", but I didn't include them for brevity, but they all follow this pattern, but with a different stateType)
Basically, the printer has a task that it is doing (in the example above, the task has an ID of 5fee231a
) and within it, sub-tasks (e.g. Task 28253266
).
If I use this code:
var vals interface{}
err = json.Unmarshal([]byte(myJSON), &vals)
if err != nil {
fmt.Println("Error:", err)
}
spew.Dump(&vals)
(using github.com/davecgh/go-spew
to dump the variable), then I get some output (NB: This isn't the whole output, it's snipped for brevity :)):
(*map[string]interface {})(0xc0820068e0)((len=1) {
(string) (len=5) "tasks": ([]interface {}) (len=1 cap=1) {
(map[string]interface {}) (len=4) {
(string) (len=5) "class": (string) (len=4) "Task",
(string) (len=2) "id": (string) (len=8) "5fee231a",
(string) (len=9) "instances": (map[string]interface {}) (len=13) {
(string) (len=8) "bd65d028": (map[string]interface {}) (len=4) {
(string) (len=5) "class": (string) (len=13) "StateInstance",
(string) (len=2) "id": (string) (len=8) "bd65d028",
(string) (len=8) "progress": (float64) 1,
(string) (len=9) "stateType": (string) (len=17) "CenteringPosition"
},
(string) (len=8) "d1e225e7": (map[string]interface {}) (len=4) {
(string) (len=2) "id": (string) (len=8) "d1e225e7",
(string) (len=8) "progress": (float64) 1,
(string) (len=9) "stateType": (string) (len=10) "TargetCold",
(string) (len=5) "class": (string) (len=13) "StateInstance"
},
This is nice, but I'd like to be be able to grab the status of a given instance (e.g. ask for the progress of X-Calibration
, get 1
in return). So I created some structs:
type Message struct {
Tasks []struct {
Class string
Id string
Instances []struct {
Something []struct {
Class string
Id string
StateType string
}
}
}
}
Tasks
gets unmarshalled, but none of the instances:
====================== Error: json: cannot unmarshal object into Go value of type []struct { Something struct { Class string; Id string; StateType string } }
(*buccaneer.Message)(0xc082002c40)({
Tasks: ([]struct { Class string; Id string; Instances []struct { Something struct { Class string; Id string; StateType string } } }) (len=1 cap=4) {
(struct { Class string; Id string; Instances []struct { Something struct { Class string; Id string; StateType string } } }) {
Class: (string) (len=4) "Task",
Id: (string) (len=8) "5fee231a",
Instances: ([]struct { Something struct { Class string; Id string; StateType string } }) <nil>
}
}
})
And note the something
struct in there. I don't know what to name that struct, as the instances have unique names (i.e. each "sub-task" has a different ID)
Any help is much appreciated :)
EDIT: Updated to show that unmarshalling is partially working, except for the Instances