package router import ( "encoding/json" "io" "net/http" "net/url" ) type DefaultError uint32 const ( DefaultErrorBadRequest DefaultError = http.StatusBadRequest DefaultErrorUnauthorized DefaultError = http.StatusUnauthorized DefaultErrorMethodNotAllowed DefaultError = http.StatusMethodNotAllowed DefaultErrorInternalServerError DefaultError = http.StatusInternalServerError DefaultErrorNotImplemented DefaultError = http.StatusNotImplemented ) func (e DefaultError) Error(Error) Error { return e } func (e DefaultError) Status() (code int) { return int(e) } func (e DefaultError) String() (out string) { switch e { case DefaultErrorBadRequest: out = "bad request" case DefaultErrorUnauthorized: out = "user unauthorized" case DefaultErrorMethodNotAllowed: out = "method not allowed" case DefaultErrorInternalServerError: out = "internal server error" case DefaultErrorNotImplemented: out = "server not implemented" default: out = "unhandled error" } return } func (e DefaultError) Response() *GenericResponse { body, err := json.Marshal(struct{ Error string }{Error: e.String()}) if err != nil { panic(err) } return &GenericResponse{ Status: e.Status(), Header: Header{"Content-Type": []string{"text/javascript", "charInit=utf-8"}}, Body: body, } } type DefaultErrorHandler struct { DefaultError } func (*DefaultErrorHandler) Error(e Error) Error { return &DefaultErrorHandler{DefaultError: e.(DefaultError)} } type DefaultRequestBuilder struct { errorHandler Error allowedMethods *[]string url *url.URL header struct { *Header fields header } values struct { *Values fields values } body struct { *Body fields body } } // Leave commented to require services to create their own New method // var _ RequestBuilder = (*DefaultRequestBuilder)(nil) // func (*DefaultRequestBuilder) New() RequestBuilder { // return NewDefaultRequestBuilder() // } func (*DefaultRequestBuilder) mustEmbedDefaultRequestBuilder() {} func NewDefaultRequestBuilder() *DefaultRequestBuilder { return &DefaultRequestBuilder{} } func (rqb *DefaultRequestBuilder) InitErrorHandler(errorHandler Error) *DefaultRequestBuilder { rqb.errorHandler = errorHandler return rqb } func (rqb *DefaultRequestBuilder) InitAllowedMethods(allowedMethods *[]string) *DefaultRequestBuilder { rqb.allowedMethods = allowedMethods return rqb } func (rqb *DefaultRequestBuilder) InitUrl(url *url.URL) *DefaultRequestBuilder { rqb.url = url return rqb } func (rqb *DefaultRequestBuilder) InitHeader(parsed *Header, fields header) *DefaultRequestBuilder { rqb.header.Header = parsed rqb.header.fields = fields return rqb } func (rqb *DefaultRequestBuilder) InitValues(parsed *Values, fields values) *DefaultRequestBuilder { rqb.values.Values = parsed rqb.values.fields = fields return rqb } func (rqb *DefaultRequestBuilder) InitBody(parsed *Body, fields body) *DefaultRequestBuilder { rqb.body.Body = parsed rqb.body.fields = fields return rqb } func (rqb *DefaultRequestBuilder) Init() *DefaultRequestBuilder { if rqb.errorHandler == nil { rqb.errorHandler = &DefaultErrorHandler{} } if rqb.allowedMethods == nil { amd := make([]string, 0) rqb.allowedMethods = &amd } if rqb.url == nil { u := url.URL{} rqb.url = &u } if rqb.header.Header == nil || rqb.header.fields == nil { hd := Header{"Content-Type": []string{"text/plain", "charset=utf-8"}} rqb.header.Header = &hd hfd := struct{ Header }{Header: hd} rqb.header.fields = &hfd } if rqb.values.Values == nil || rqb.values.fields == nil { vd := make(Values) rqb.values.Values = &vd vfd := struct{ Values }{Values: vd} rqb.values.fields = &vfd } if rqb.body.Body == nil || rqb.body.fields == nil { bd := make(Body, 0) rqb.body.Body = &bd bfd := struct{ Body }{Body: bd} rqb.body.fields = &bfd } return rqb } func (rqb *DefaultRequestBuilder) SetAllowed(method string) (e Error) { var ok bool for _, m := range *rqb.allowedMethods { if m == method { ok = true } } if !ok { return rqb.errorHandler.Error(DefaultErrorMethodNotAllowed) } return } func (rqb *DefaultRequestBuilder) SetUrl(url url.URL) (e Error) { *rqb.url = url return } func (rqb *DefaultRequestBuilder) SetHeader(header map[string][]string) (e Error) { *rqb.header.Header = header err := rqb.header.Header.Unmarshal(rqb.header.fields) if err != nil { return rqb.errorHandler.Error(DefaultErrorBadRequest) } return } func (rqb *DefaultRequestBuilder) SetBody(body io.ReadCloser) (e Error) { defer body.Close() json.NewDecoder(body).Decode(rqb.body.fields) return } func (rqb *DefaultRequestBuilder) SetValues(values map[string][]string) (e Error) { *rqb.values.Values = values err := rqb.values.Values.Unmarshal(rqb.values.fields) if err != nil { return rqb.errorHandler.Error(DefaultErrorBadRequest) } return } func (rqb *DefaultRequestBuilder) Request() (req *GenericRequest) { req = &GenericRequest{ Url: *rqb.url, Header: *rqb.header.Header, Values: *rqb.values.Values, Body: *rqb.body.Body, } return } type DefaultResponseBuilder struct { errorHandler Error status *int header struct { *Header fields header } body struct { *Body fields body } } // Leave commented to require services to create their own New method // var _ ResponseBuilder = (*DefaultResponseBuilder)(nil) // func (rsb *DefaultResponseBuilder) New() ResponseBuilder { // return NewDefaultResponseBuilder() // } func (*DefaultResponseBuilder) mustEmbedDefaultResponseBuilder() {} func NewDefaultResponseBuilder() *DefaultResponseBuilder { return &DefaultResponseBuilder{} } func (rsb *DefaultResponseBuilder) InitErrorHandler(errorHandler Error) *DefaultResponseBuilder { rsb.errorHandler = errorHandler return rsb } func (rsb *DefaultResponseBuilder) InitStatus(code *int) *DefaultResponseBuilder { rsb.status = code return rsb } func (rsb *DefaultResponseBuilder) InitHeader(parsed *Header, fields header) *DefaultResponseBuilder { rsb.header.Header = parsed rsb.header.fields = fields return rsb } func (rsb *DefaultResponseBuilder) InitBody(parsed *Body, fields body) *DefaultResponseBuilder { rsb.body.Body = parsed rsb.body.fields = fields return rsb } func (rsb *DefaultResponseBuilder) Init() *DefaultResponseBuilder { if rsb.errorHandler == nil { rsb.errorHandler = &DefaultErrorHandler{} } if rsb.status == nil { c := http.StatusOK rsb.status = &c } if rsb.header.Header == nil || rsb.header.fields == nil { hd := Header{"Content-Type": []string{"text/plain", "charset=utf-8"}} rsb.header.Header = &hd hfd := struct{ Header }{Header: hd} rsb.header.fields = &hfd } if rsb.body.Body == nil || rsb.body.fields == nil { bd := make(Body, 0) rsb.body.Body = &bd bfd := struct{ Body }{Body: bd} rsb.body.fields = &bfd } return rsb } func (rsb *DefaultResponseBuilder) SetHeader(header map[string][]string) (e Error) { *rsb.header.Header = header err := rsb.header.Header.Unmarshal(rsb.header.fields) if err != nil { return rsb.errorHandler.Error(DefaultErrorInternalServerError) } return } func (rsb *DefaultResponseBuilder) SetBody(body []byte) (e Error) { *rsb.body.Body = body return } func (rsb *DefaultResponseBuilder) Response() (res *GenericResponse) { res = &GenericResponse{ Status: *rsb.status, Header: *rsb.header.Header, Body: *rsb.body.Body, } return }