diff --git a/body.go b/body.go index 1a1c172..75bf0fe 100644 --- a/body.go +++ b/body.go @@ -43,10 +43,9 @@ func BodyBytes(b []byte) BodyGetter { } } -// BodyJSON is a BodyGetter that marshals a JSON object. -func BodyJSON(v any) BodyGetter { +func BodySerializer(s Serializer, v any) BodyGetter { return func() (io.ReadCloser, error) { - b, err := jsonMarshal(v) + b, err := s(v) if err != nil { return nil, err } @@ -54,6 +53,11 @@ func BodyJSON(v any) BodyGetter { } } +// BodyJSON is a BodyGetter that marshals a JSON object. +func BodyJSON(v any) BodyGetter { + return BodySerializer(JSONSerializer, v) +} + // BodyForm is a BodyGetter that builds an encoded form body. func BodyForm(data url.Values) BodyGetter { return func() (r io.ReadCloser, err error) { diff --git a/builder_extras.go b/builder_extras.go index 4ed7fbc..1448c1f 100644 --- a/builder_extras.go +++ b/builder_extras.go @@ -133,6 +133,11 @@ func (rb *Builder) BodyBytes(b []byte) *Builder { return rb.Body(BodyBytes(b)) } +func (rb *Builder) BodySerializer(s Serializer, v any) *Builder { + return rb. + Body(BodySerializer(s, v)) +} + // BodyJSON sets the Builder's request body to the marshaled JSON. // It also sets ContentType to "application/json". func (rb *Builder) BodyJSON(v any) *Builder { @@ -169,6 +174,11 @@ func (rb *Builder) CheckPeek(n int, f func([]byte) error) *Builder { return rb.AddValidator(CheckPeek(n, f)) } +func (rb *Builder) ToDeserializer(d Deserializer, v any) *Builder { + return rb. + Handle(ToDeserializer(d, v)) +} + // ToJSON sets the Builder to decode a response as a JSON object func (rb *Builder) ToJSON(v any) *Builder { return rb.Handle(ToJSON(v)) diff --git a/handler.go b/handler.go index 590c8cf..78e0a75 100644 --- a/handler.go +++ b/handler.go @@ -38,20 +38,24 @@ func consumeBody(res *http.Response) (err error) { return err } -// ToJSON decodes a response as a JSON object. -func ToJSON(v any) ResponseHandler { +func ToDeserializer(d Deserializer, v any) ResponseHandler { return func(res *http.Response) error { data, err := io.ReadAll(res.Body) if err != nil { return err } - if err = jsonUnmarshal(data, v); err != nil { + if err = d(data, v); err != nil { return err } return nil } } +// ToJSON decodes a response as a JSON object. +func ToJSON(v any) ResponseHandler { + return ToDeserializer(JSONDeserializer, v) +} + // ToString writes the response body to the provided string pointer. func ToString(sp *string) ResponseHandler { return func(res *http.Response) error { diff --git a/json.go b/json.go index 62a9331..bb93081 100644 --- a/json.go +++ b/json.go @@ -4,25 +4,10 @@ import ( "encoding/json" ) -type jsonMarshaller = func(v any) ([]byte, error) -type jsonUnmarshaller = func(data []byte, v any) error +type Serializer = func(v any) ([]byte, error) +type Deserializer = func(data []byte, v any) error var ( - jsonMarshal = json.Marshal - jsonUnmarshal = json.Unmarshal + JSONSerializer = json.Marshal + JSONDeserializer = json.Unmarshal ) - -func SetJSONUnmarshaller(j jsonUnmarshaller) { - jsonUnmarshal = j -} - -func SetJSONMarshaller(j jsonMarshaller) { - jsonMarshal = j -} - -// SetJSONSerializers is a function to set global json.Marshal/json.Unmarshal function -// For faster serialization/deserialization you can use functions from, for instance, https://github.com/goccy/go-json -func SetJSONSerializers(marshaller jsonMarshaller, unmarshaller jsonUnmarshaller) { - jsonMarshal = marshaller - jsonUnmarshal = unmarshaller -} diff --git a/reqxml/body.go b/reqxml/body.go index 6c220df..cc15619 100644 --- a/reqxml/body.go +++ b/reqxml/body.go @@ -2,20 +2,13 @@ package reqxml import ( "encoding/xml" - "io" "github.com/carlmjohnson/requests" ) // Body is a BodyGetter that marshals a XML object. func Body(v any) requests.BodyGetter { - return func() (io.ReadCloser, error) { - b, err := xml.Marshal(v) - if err != nil { - return nil, err - } - return requests.BodyBytes(b)() - } + return requests.BodySerializer(xml.Marshal, v) } // BodyConfig sets the Builder's request body to the marshaled XML. diff --git a/reqxml/to.go b/reqxml/to.go index 6907cd4..c7b61a5 100644 --- a/reqxml/to.go +++ b/reqxml/to.go @@ -2,22 +2,11 @@ package reqxml import ( "encoding/xml" - "io" - "net/http" "github.com/carlmjohnson/requests" ) // To decodes a response as an XML object. func To(v any) requests.ResponseHandler { - return func(res *http.Response) error { - data, err := io.ReadAll(res.Body) - if err != nil { - return err - } - if err = xml.Unmarshal(data, v); err != nil { - return err - } - return nil - } + return requests.ToDeserializer(xml.Unmarshal, v) }