1
0
mirror of https://github.com/MontFerret/ferret.git synced 2024-12-14 11:23:02 +02:00
ferret/pkg/drivers/response.go
Владимир Фетисов 73c9a01af5 add HTTPResponse
2019-09-30 21:00:13 +03:00

104 lines
2.2 KiB
Go

package drivers
import (
"context"
"encoding/json"
"strings"
"github.com/MontFerret/ferret/pkg/runtime/core"
"github.com/MontFerret/ferret/pkg/runtime/values"
"github.com/MontFerret/ferret/pkg/runtime/values/types"
)
// HTTPResponse HTTP response object.
type HTTPResponse struct {
StatusCode int
Status string
Headers HTTPHeaders
}
func (resp *HTTPResponse) Type() core.Type {
return HTTPResponseType
}
func (resp *HTTPResponse) String() string {
return resp.Status
}
func (resp *HTTPResponse) Compare(other core.Value) int64 {
if other.Type() != HTTPResponseType {
return Compare(HTTPResponseType, other.Type())
}
otherObj := values.Parse(other)
respObj := values.Parse(resp)
// HTTPHeaders has it's own Compare
respObj.(*values.Object).Set(
values.NewString("Headers"),
resp.Headers,
)
otherObj.(*values.Object).Set(
values.NewString("Headers"),
other.(*HTTPResponse).Headers,
)
return respObj.Compare(otherObj)
}
func (resp *HTTPResponse) Unwrap() interface{} {
return resp
}
func (resp *HTTPResponse) Copy() core.Value {
return *(&resp)
}
func (resp *HTTPResponse) Hash() uint64 {
return values.Parse(resp).Hash()
}
// responseMarshal is a structure that repeats HTTPResponse. It allows
// easily Marshal the HTTPResponse object.
type responseMarshal struct {
StatusCode int `json:"status_code"`
Status string `json:"status"`
Headers HTTPHeaders `json:"headers"`
}
func (resp *HTTPResponse) MarshalJSON() ([]byte, error) {
if resp == nil {
return json.Marshal(values.None)
}
return json.Marshal(responseMarshal(*resp))
}
func (resp *HTTPResponse) GetIn(ctx context.Context, path []core.Value) (core.Value, error) {
if len(path) == 0 {
return resp, nil
}
if typ := path[0].Type(); typ != types.String {
return values.None, core.TypeError(typ, types.String)
}
field := path[0].(values.String).String()
field = strings.ToLower(field)
switch field {
case "status":
return values.NewString(resp.Status), nil
case "status_code", "statusCode":
return values.NewInt(resp.StatusCode), nil
case "headers":
if len(path) == 1 {
return resp.Headers, nil
}
return resp.Headers.GetIn(ctx, path[1:])
}
return values.None, nil
}