代码拉取完成,页面将自动刷新
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)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。