-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathresult.go
118 lines (97 loc) · 2.27 KB
/
result.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
108
109
110
111
112
113
114
115
116
117
118
package hermes
import (
"encoding/json"
"fmt"
"io"
"reflect"
"github.com/lab259/errors/v2"
"github.com/valyala/bytebufferpool"
"github.com/valyala/fasthttp"
)
type result struct {
r *fasthttp.RequestCtx
status int
hasSentData bool
}
func (r *result) Data(data interface{}) Result {
if r.hasSentData {
return r
}
if err, ok := data.(error); ok {
return r.Error(err)
}
if v, ok := data.([]byte); ok {
r.r.Response.AppendBody(v)
} else if v, ok := data.(io.Reader); ok {
io.Copy(r.r.Response.BodyWriter(), v)
} else {
dataType := reflect.TypeOf(data)
if dataType.Kind() == reflect.Ptr {
dataType = dataType.Elem()
}
switch dataType.Kind() {
case reflect.Struct, reflect.Array, reflect.Slice, reflect.Map:
r.setContentType(defaultJSONContentType)
e := json.NewEncoder(r.r.Response.BodyWriter())
if err := e.Encode(data); err != nil {
return r.Error(err)
}
default:
r.setContentType(defaultContentType)
r.r.Response.AppendBodyString(fmt.Sprintf("%v", data))
}
}
r.setStatus()
r.hasSentData = true
return r
}
func (r *result) Error(err error) Result {
if err == nil {
return r
}
errResponse := acquireErrorResponse(StatusInternalServerError)
if !errors.AggregateToResponse(err, errResponse) {
errResponse.SetParam("code", InternalServerErrorCode)
errResponse.SetParam("message", InternalServerErrorMessage)
}
r.defaultStatus(errResponse.Status)
r.Data(errResponse.Data)
releaseErrorResponse(errResponse)
return r
}
func (r *result) setStatus() {
if r.status == 0 {
r.status = StatusOK
}
r.r.SetStatusCode(r.status)
}
func (r *result) setContentType(v []byte) {
r.r.SetContentTypeBytes(v)
}
func (r *result) defaultStatus(code int) {
if r.status == 0 {
r.status = code
}
}
func (r *result) Redirect(uri string, code int) Result {
r.r.Redirect(uri, code)
return r
}
func (r *result) File(filepath string) Result {
r.r.SendFile(filepath)
return r
}
func (r *result) FileDownload(filepath, filename string) Result {
r.r.SendFile(filepath)
buff := bytebufferpool.Get()
buff.SetString("attachment; filename=")
buff.WriteString(filename)
r.r.Response.Header.Set("Content-Disposition", buff.String())
bytebufferpool.Put(buff)
return r
}
func (r *result) End() {
r.r = nil
r.status = 0
r.hasSentData = false
}