router/default.go

240 lines
4.9 KiB
Go

package router
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
type DefaultError uint32
type DefaultErrorHandler struct {
DefaultError
}
func (*DefaultErrorHandler) ErrorResponse(errorResponse ErrorResponse) ErrorResponse {
return DefaultErrorHandler{errorResponse.(DefaultError)}
}
const (
DefaultOk DefaultError = http.StatusOK
DefaultErrorNotImplemented DefaultError = http.StatusNotImplemented
DefaultErrorMethodNotAllowed DefaultError = http.StatusMethodNotAllowed
DefaultErrorBadRequest DefaultError = http.StatusBadRequest
DefaultErrorUnauthorized DefaultError = http.StatusUnauthorized
DefaultErrorServerError DefaultError = http.StatusInternalServerError
)
func (e DefaultError) Ok() (ok bool) {
return e == DefaultOk
}
func (e DefaultError) HttpStatus() (code int) {
return int(e)
}
func (e DefaultError) String() (out string) {
switch e {
case DefaultOk:
out = "ok"
case DefaultErrorNotImplemented:
out = "server not implemented"
case DefaultErrorMethodNotAllowed:
out = "method not allowed"
case DefaultErrorBadRequest:
out = "bad request"
case DefaultErrorUnauthorized:
out = "user unauthorized"
case DefaultErrorServerError:
out = "internal server error"
default:
out = "unhandled error"
}
return
}
func (e DefaultError) Error() (out string) {
return fmt.Sprintf("%s (%d)", e.String(), e.HttpStatus())
}
func (e DefaultError) BodyBytes() (body []byte) {
body, _ = json.Marshal(struct{ Error string }{Error: e.String()})
return
}
type DefaultRequestBuilder struct {
requestBuilder RequestBuilder
prototype PrototypeRequestBuilder
errorHandler ErrorHandler
allowedMethods *[]string
header struct {
*Header
fields header
}
values struct {
*Values
fields values
}
body struct {
*Body
fields body
}
}
func NewDefaultRequestBuilder(rb RequestBuilder, rbp PrototypeRequestBuilder, eh ErrorHandler, am *[]string, h *Header, hf header, v *Values, vf values, b *Body, bf body) DefaultRequestBuilder {
if eh == nil {
eh = &DefaultErrorHandler{}
}
if am == nil {
amd := make([]string, 0)
am = &amd
}
if h == nil || hf == nil {
hd := make(Header)
h = &hd
hfd := struct{ Header }{Header: hd}
hf = &hfd
}
if v == nil || vf == nil {
vd := make(Values)
v = &vd
vfd := struct{ Values }{Values: vd}
vf = &vfd
}
if b == nil || bf == nil {
bd := make(Body, 0)
b = &bd
bfd := struct{ Body }{Body: bd}
bf = &bfd
}
return DefaultRequestBuilder{
requestBuilder: rb,
prototype: rbp,
errorHandler: eh,
allowedMethods: am,
header: struct {
*Header
fields header
}{
Header: h,
fields: hf,
},
values: struct {
*Values
fields values
}{
Values: v,
fields: vf,
},
body: struct {
*Body
fields body
}{
Body: b,
fields: bf,
},
}
}
func (rb *DefaultRequestBuilder) Prototype() PrototypeRequestBuilder {
return rb.prototype
}
func (rb *DefaultRequestBuilder) Allowed(method string) (errRes ErrorResponse) {
var ok bool
for _, m := range *rb.allowedMethods {
if m == method {
ok = true
}
}
if !ok {
return rb.errorHandler.ErrorResponse(DefaultErrorMethodNotAllowed)
}
return DefaultOk
}
func (rb *DefaultRequestBuilder) Header(header Header) (errRes ErrorResponse) {
err := rb.header.Header.Parse(header)
if err != nil {
return rb.errorHandler.ErrorResponse(DefaultErrorBadRequest)
}
return rb.errorHandler.ErrorResponse(DefaultOk)
}
func (rb *DefaultRequestBuilder) ReadBody(body io.ReadCloser) (errRes ErrorResponse) {
defer body.Close()
json.NewDecoder(body).Decode(rb.body.fields)
return rb.errorHandler.ErrorResponse(DefaultOk)
}
func (rb *DefaultRequestBuilder) Values(values Values) (errRes ErrorResponse) {
err := rb.values.Values.Parse(values)
if err != nil {
return rb.errorHandler.ErrorResponse(DefaultErrorBadRequest)
}
return rb.errorHandler.ErrorResponse(DefaultOk)
}
type DefaultResponse struct {
response Response
prototype PrototypeResponse
header struct {
*Header
fields header
}
body struct {
*Body
fields body
}
}
func NewDefaultResponse(r Response, rp PrototypeResponse, h *Header, hf header, b *Body, bf body) DefaultResponse {
if h == nil || hf == nil {
hd := make(Header)
h = &hd
hfd := struct{ Header }{Header: hd}
hf = &hfd
}
if b == nil || bf == nil {
bd := make(Body, 0)
b = &bd
bfd := struct{ Body }{Body: bd}
bf = &bfd
}
return DefaultResponse{
response: r,
prototype: rp,
header: struct {
*Header
fields header
}{
Header: h,
fields: hf,
},
body: struct {
*Body
fields body
}{
Body: b,
fields: bf,
},
}
}
func (r *DefaultResponse) Prototype() PrototypeResponse {
return r.prototype
}
func (r *DefaultResponse) Header() (header Header) {
if r.header.Header == nil {
r.header.Header.Parse(r.header.fields)
}
return *r.header.Header
}
func (r *DefaultResponse) BodyBytes() (body []byte) {
body, _ = json.Marshal(r.body.fields)
return
}