diff --git a/pkg/drivers/response.go b/pkg/drivers/response.go new file mode 100644 index 00000000..919c1725 --- /dev/null +++ b/pkg/drivers/response.go @@ -0,0 +1,103 @@ +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 +} diff --git a/pkg/drivers/type.go b/pkg/drivers/type.go index 674adce4..aa282d95 100644 --- a/pkg/drivers/type.go +++ b/pkg/drivers/type.go @@ -3,6 +3,7 @@ package drivers import "github.com/MontFerret/ferret/pkg/runtime/core" var ( + HTTPResponseType = core.NewType("HTTPResponse") HTTPHeaderType = core.NewType("HTTPHeaders") HTTPCookieType = core.NewType("HTTPCookie") HTMLElementType = core.NewType("HTMLElement")