-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
107 lines (89 loc) · 2.64 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package fhir
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/gotidy/fhir-client/models"
"github.com/tidwall/gjson"
)
type ResourceType string
func (r ResourceType) String() string {
return string(r)
}
type ResourceData []byte
func (r ResourceData) String() string {
return string(r)
}
func (r ResourceData) UnmarshalTo(v interface{}) error {
return json.Unmarshal(r, v)
}
type Parameters interface {
Encode() string
}
type FhirResponse struct {
StatusCode int
Body []byte
Bundle *models.Bundle
OperationOutcome *models.OperationOutcome
ResourceType ResourceType
}
func NewFhirResponse(resp *http.Response) (*FhirResponse, error) {
fresp := &FhirResponse{
StatusCode: resp.StatusCode,
}
var err error
fresp.Body, err = ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
return fresp, err
}
if contentType := resp.Header.Get("Content-Type"); !strings.Contains(contentType, "json") {
return fresp, NewResponseError(resp, fmt.Sprintf("Content-Type is \"%s\" but expected \"application/json\"", contentType))
}
var message string
fresp.ResourceType = GetDataResourceType(fresp.Body)
switch fresp.ResourceType {
case "Bundle":
var dest models.Bundle
if err := json.Unmarshal(fresp.Body, &dest); err != nil {
return fresp, NewUnmarshalError("response parsing", fresp.ResourceType, fresp.Body, err)
}
fresp.Bundle = &dest
case "OperationOutcome":
var dest models.OperationOutcome
if err := json.Unmarshal(fresp.Body, &dest); err != nil {
return fresp, NewUnmarshalError("response parsing", fresp.ResourceType, fresp.Body, err)
}
fresp.OperationOutcome = &dest
case "":
message = gjson.GetBytes(fresp.Body, "message").String()
}
switch {
case resp.StatusCode >= 200 && resp.StatusCode < 300:
return fresp, nil
case resp.StatusCode >= 400 && resp.StatusCode < 500:
return fresp, NewFhirError(resp, fresp.OperationOutcome, message)
default:
return fresp, NewResponseError(resp, fmt.Sprintf("unexpected respose status: %d %s", resp.StatusCode, http.StatusText(resp.StatusCode)))
}
}
func (r *FhirResponse) MustBundle() error {
if r.Bundle == nil {
return fmt.Errorf("expected Bundle data in the response, but have: %s", r.ResourceType)
}
return nil
}
func (r *FhirResponse) MustResourceData(resource ResourceType) error {
if r.Body == nil && r.ResourceType != resource {
return fmt.Errorf("expected resource data in the response")
}
return nil
}
func (r *FhirResponse) MustOperationOutcome() error {
if r.Bundle == nil {
return fmt.Errorf("expected OperationOutcome data in the response, but have: %s", r.ResourceType)
}
return nil
}