11 type apiResponse struct {
22 type response struct {
27 func parseResponse(r io.Reader) (*response, error) {
28 var apiresp apiResponse
29 if err := json.NewDecoder(r).Decode(&apiresp); err != nil {
32 // Confusingly the top-level status field in an API response contains
33 // an error message. Successful statuses are actually held in the
34 // status field in Results!
35 if apiresp.Status != "" {
36 return &response{Error: errors.New(apiresp.Status)}, nil
39 for _, r := range apiresp.Results {
40 if len(r.Errors) > 0 {
41 resp.Error = errors.New(strings.Join(r.Errors, ", "))
42 // got an error so nothing left in the API response
52 if err := json.Unmarshal(r.Attrs, &h); err != nil {
55 resp.Results = append(resp.Results, h)
59 if err := json.Unmarshal(r.Attrs, &s); err != nil {
62 resp.Results = append(resp.Results, s)
66 if err := json.Unmarshal(r.Attrs, &u); err != nil {
69 resp.Results = append(resp.Results, u)
73 if err := json.Unmarshal(r.Attrs, &h); err != nil {
76 resp.Results = append(resp.Results, h)
78 return nil, fmt.Errorf("unsupported unmarshal of type %s", r.Type)
84 func objectFromLookup(resp *response) (object, error) {
85 if len(resp.Results) == 0 {
86 return nil, errors.New("empty results")
87 } else if len(resp.Results) > 1 {
88 return nil, errors.New("too many results")
90 return resp.Results[0], nil