package kernel import ( "encoding/json" "errors" ) // unmarshalKernelResponse performs custom unmarshaling for kernel responses, checks for presence of `error` key on json // and returns if present. // // The uresult parameter may be passed to json.Unmarshal so if unmarshalKernelResponse is called within a custom // UnmarshalJSON function, it must be a type alias (otherwise, this will recurse into itself until the stack is full). // The result parameter must point to the original result (with the original type). This unfortunate duplication is // necessary for the proper handling of in-line callbacks. func unmarshalKernelResponse(data []byte, uresult kernelResponder, result kernelResponder) error { datacopy := make([]byte, len(data)) copy(datacopy, data) var response map[string]json.RawMessage if err := json.Unmarshal(datacopy, &response); err != nil { return err } if err, ok := response["error"]; ok { return errors.New(string(err)) } // In-line callback requests interrupt the current flow, the callback handling // logic will resume this handling once the callback request has been fulfilled. if raw, ok := response["callback"]; ok { callback := callback{} if err := json.Unmarshal(raw, &callback); err != nil { return err } return callback.handle(result) } return json.Unmarshal(response["ok"], uresult) }