1 Star 2 Fork 3

kristas/booting-go

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
response.go 3.83 KB
一键复制 编辑 原始数据 按行查看 历史
kristas 提交于 2021-08-27 00:23 +08:00 . feat: rebuild response
package resp
import (
"bytes"
"encoding/json"
"errors"
"html/template"
"io/fs"
"log"
"net/http"
)
type Marshaller func(data interface{}) []byte
// Response define standard response function
type Response interface {
//build response
Status(httpCode int) Response
Data(data interface{}) Response
Marshaller(marshaller Marshaller) Response
ContentType(cType string) Response
GetStatus() int
GetData() interface{}
GetContentType() string
GetMarshaller() Marshaller
// Write the response
// when content-type is application/json, data will auto marshal to json
// other time will convert to string
Write(w http.ResponseWriter)
//error
Error() string
}
type r struct {
status int
data interface{}
contentType string
marshaller Marshaller
}
func (r *r) Status(httpCode int) Response {
r.status = httpCode
return r
}
func (r *r) Data(data interface{}) Response {
r.data = data
return r
}
func (r *r) Marshaller(marshaller Marshaller) Response {
r.marshaller = marshaller
return r
}
func (r *r) ContentType(cType string) Response {
r.contentType = cType
return r
}
func (r *r) GetStatus() int {
return r.status
}
func (r *r) GetData() interface{} {
return r.data
}
func (r *r) GetMarshaller() Marshaller {
if r.marshaller != nil {
return r.marshaller
}
if marshaller, ok := autoMarshaller[r.GetContentType()]; ok {
r.marshaller = marshaller
} else {
r.marshaller = RawMarshaller
}
return r.marshaller
}
func (r r) GetContentType() string {
return r.contentType
}
func (r *r) write(w http.ResponseWriter, data []byte) {
w.Header().Set(ContentTypeHeaderKey, ContentType(r.GetContentType()))
w.WriteHeader(r.GetStatus())
_, err := w.Write(data)
if err != nil {
log.Println(err.Error())
}
}
func (r *r) Write(w http.ResponseWriter) {
r.write(w, r.GetMarshaller()(r.GetData()))
}
func (r *r) Error() string {
return string(r.GetMarshaller()(r.GetData()))
}
/*
Template
*/
type IModelAndView interface {
SetModel(model interface{}) IModelAndView
SetAttributes(key string, value interface{}) IModelAndView
SetView(file string) IModelAndView
SetFS(fs fs.FS, file string) IModelAndView
Compile() (raw string, err error)
Response() Response
Write(w http.ResponseWriter)
}
type mode string
const (
viewMode mode = "view"
fsMode mode = "fs"
)
type mv struct {
view string
fs fs.FS
mode mode
model map[string]interface{}
}
func (r *mv) SetModel(model interface{}) IModelAndView {
var modelMap map[string]interface{}
modelBytes, _ := json.Marshal(model)
json.Unmarshal(modelBytes, &modelMap)
r.model = modelMap
return r
}
func (r *mv) SetAttributes(key string, value interface{}) IModelAndView {
if r.model == nil {
r.model = make(map[string]interface{})
}
r.model[key] = value
return r
}
func (r *mv) SetView(file string) IModelAndView {
r.view = file
r.mode = viewMode
return r
}
func (r *mv) SetFS(fs fs.FS, file string) IModelAndView {
r.mode = fsMode
r.fs = fs
r.view = file
return r
}
func (r *mv) Compile() (raw string, err error) {
var tpl *template.Template
switch r.mode {
case viewMode:
tpl, err = template.ParseFiles(r.view)
if err != nil {
return
}
var buf bytes.Buffer
err = tpl.Execute(&buf, r.model)
if err != nil {
return
}
raw = buf.String()
return
case fsMode:
tpl, err = template.ParseFS(r.fs, r.view)
if err != nil {
return
}
var buf bytes.Buffer
err = tpl.Execute(&buf, r.model)
if err != nil {
return
}
raw = buf.String()
return
default:
return "", errors.New("view not set")
}
}
func (r *mv) Response() Response {
raw, err := r.Compile()
if err != nil {
return ErrInternalError(err)
}
return New(raw).ContentType(ContentHTMLHeaderValue)
}
func (r *mv) Write(w http.ResponseWriter) {
raw, err := r.Compile()
if err != nil {
ErrInternalError(err).Write(w)
}
New(raw).ContentType(ContentHTMLHeaderValue).Write(w)
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/kristas/booting-go.git
git@gitee.com:kristas/booting-go.git
kristas
booting-go
booting-go
v1.4.4

搜索帮助