11 type apiResponse struct {
21 type response struct {
26 func parseAPIResponse(r io.Reader) (apiResponse, error) {
27 var apiresp apiResponse
28 if err := json.NewDecoder(r).Decode(&apiresp); err != nil {
29 return apiResponse{}, err
34 func parseResponse(r io.Reader) (*response, error) {
35 apiresp, err := parseAPIResponse(r)
39 // Confusingly the top-level status field in an API response contains
40 // an error message. Successful statuses are actually held in the
41 // status field in Results!
42 if apiresp.Status != "" {
43 return &response{Error: errors.New(apiresp.Status)}, nil
46 for _, r := range apiresp.Results {
47 if len(r.Errors) > 0 {
48 resp.Error = errors.New(strings.Join(r.Errors, ", "))
49 // got an error so nothing left in the API response
58 if err := json.Unmarshal(r.Attrs, &h); err != nil {
61 resp.Results = append(resp.Results, h)
64 if err := json.Unmarshal(r.Attrs, &s); err != nil {
67 resp.Results = append(resp.Results, s)
70 if err := json.Unmarshal(r.Attrs, &u); err != nil {
73 resp.Results = append(resp.Results, u)
76 if err := json.Unmarshal(r.Attrs, &h); err != nil {
79 resp.Results = append(resp.Results, h)
81 return nil, fmt.Errorf("unsupported unmarshal of type %s", r.Type)
87 func objectFromLookup(resp *response) (object, error) {
88 if len(resp.Results) == 0 {
89 return nil, errors.New("empty results")
90 } else if len(resp.Results) > 1 {
91 return nil, errors.New("too many results")
93 return resp.Results[0], nil