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 { errorHandler ErrorHandler allowedMethods *[]string header struct { *Header fields header } values struct { *Values fields values } body struct { *Body fields body } } func NewDefaultRequestBuilder() *DefaultRequestBuilder { return &DefaultRequestBuilder{} } func (rb *DefaultRequestBuilder) SetErrorHandler(errorHandler ErrorHandler) *DefaultRequestBuilder { rb.errorHandler = errorHandler return rb } func (rb *DefaultRequestBuilder) SetAllowedMethods(allowedMethods []string) *DefaultRequestBuilder { rb.allowedMethods = &allowedMethods return rb } func (rb *DefaultRequestBuilder) SetHeader(parsed *Header, fields header) *DefaultRequestBuilder { rb.header.Header = parsed rb.header.fields = fields return rb } func (rb *DefaultRequestBuilder) SetValues(parsed *Values, fields values) *DefaultRequestBuilder { rb.values.Values = parsed rb.values.fields = fields return rb } func (rb *DefaultRequestBuilder) SetBody(parsed *Body, fields body) *DefaultRequestBuilder { rb.body.Body = parsed rb.body.fields = fields return rb } func (rb *DefaultRequestBuilder) SetDefaults() *DefaultRequestBuilder { if rb.errorHandler == nil { rb.errorHandler = &DefaultErrorHandler{} } if rb.allowedMethods == nil { amd := make([]string, 0) rb.allowedMethods = &amd } if rb.header.Header == nil || rb.header.fields == nil { hd := make(Header) rb.header.Header = &hd hfd := struct{ Header }{Header: hd} rb.header.fields = &hfd } if rb.values.Values == nil || rb.values.fields == nil { vd := make(Values) rb.values.Values = &vd vfd := struct{ Values }{Values: vd} rb.values.fields = &vfd } if rb.body.Body == nil || rb.body.fields == nil { bd := make(Body, 0) rb.body.Body = &bd bfd := struct{ Body }{Body: bd} rb.body.fields = &bfd } return rb } 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 { header struct { *Header fields header } body struct { *Body fields body } } func NewDefaultResponse() *DefaultResponse { return &DefaultResponse{} } func (r *DefaultResponse) SetHeader(parsed *Header, fields header) *DefaultResponse { r.header.Header = parsed r.header.fields = fields return r } func (r *DefaultResponse) SetBody(parsed *Body, fields body) *DefaultResponse { r.body.Body = parsed r.body.fields = fields return r } func (r *DefaultResponse) SetDefaults() *DefaultResponse { if r.header.Header == nil || r.header.fields == nil { hd := make(Header) r.header.Header = &hd hfd := struct{ Header }{Header: hd} r.header.fields = &hfd } if r.body.Body == nil || r.body.fields == nil { bd := make(Body, 0) r.body.Body = &bd bfd := struct{ Body }{Body: bd} r.body.fields = &bfd } return r } 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 }