11 76669f9b 2022-01-11 o type apiResponse struct {
12 76669f9b 2022-01-11 o Results []struct {
15 76669f9b 2022-01-11 o Errors []string
16 76669f9b 2022-01-11 o Attrs json.RawMessage
21 76669f9b 2022-01-11 o type response struct {
22 76669f9b 2022-01-11 o Results []object
26 76669f9b 2022-01-11 o func parseAPIResponse(r io.Reader) (apiResponse, error) {
27 76669f9b 2022-01-11 o var apiresp apiResponse
28 76669f9b 2022-01-11 o if err := json.NewDecoder(r).Decode(&apiresp); err != nil {
29 76669f9b 2022-01-11 o return apiResponse{}, err
31 76669f9b 2022-01-11 o return apiresp, nil
34 76669f9b 2022-01-11 o func parseResponse(r io.Reader) (*response, error) {
35 76669f9b 2022-01-11 o apiresp, err := parseAPIResponse(r)
36 76669f9b 2022-01-11 o if err != nil {
37 76669f9b 2022-01-11 o return nil, err
39 76669f9b 2022-01-11 o // Confusingly the top-level status field in an API response contains
40 76669f9b 2022-01-11 o // an error message. Successful statuses are actually held in the
41 76669f9b 2022-01-11 o // status field in Results!
42 76669f9b 2022-01-11 o if apiresp.Status != "" {
43 76669f9b 2022-01-11 o return &response{Error: errors.New(apiresp.Status)}, nil
45 76669f9b 2022-01-11 o resp := &response{}
46 76669f9b 2022-01-11 o for _, r := range apiresp.Results {
47 76669f9b 2022-01-11 o if len(r.Errors) > 0 {
48 76669f9b 2022-01-11 o resp.Error = errors.New(strings.Join(r.Errors, ", "))
49 76669f9b 2022-01-11 o // got an error so nothing left in the API response
52 76669f9b 2022-01-11 o if r.Type == "" {
55 76669f9b 2022-01-11 o switch r.Type {
58 76669f9b 2022-01-11 o if err := json.Unmarshal(r.Attrs, &h); err != nil {
59 76669f9b 2022-01-11 o return nil, err
61 76669f9b 2022-01-11 o resp.Results = append(resp.Results, h)
62 76669f9b 2022-01-11 o case "Service":
64 76669f9b 2022-01-11 o if err := json.Unmarshal(r.Attrs, &s); err != nil {
65 76669f9b 2022-01-11 o return nil, err
67 76669f9b 2022-01-11 o resp.Results = append(resp.Results, s)
70 76669f9b 2022-01-11 o if err := json.Unmarshal(r.Attrs, &u); err != nil {
71 76669f9b 2022-01-11 o return nil, err
73 76669f9b 2022-01-11 o resp.Results = append(resp.Results, u)
75 76669f9b 2022-01-11 o return nil, fmt.Errorf("unsupported unmarshal of type %s", r.Type)
78 76669f9b 2022-01-11 o return resp, nil
81 76669f9b 2022-01-11 o func objectFromLookup(resp *response) (object, error) {
82 76669f9b 2022-01-11 o if len(resp.Results) == 0 {
83 76669f9b 2022-01-11 o return nil, errors.New("empty results")
84 76669f9b 2022-01-11 o } else if len(resp.Results) > 1 {
85 76669f9b 2022-01-11 o return nil, errors.New("too many results")
87 76669f9b 2022-01-11 o return resp.Results[0], nil