Skip to content

Commit

Permalink
👷 Add JSONEncoder and JSONDecoder
Browse files Browse the repository at this point in the history
  • Loading branch information
kiyonlin committed Feb 20, 2021
1 parent c477128 commit c34ca83
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 34 deletions.
44 changes: 42 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"sync"
"time"

"github.com/gofiber/fiber/v2/utils"

"github.com/gofiber/fiber/v2/internal/encoding/json"
"github.com/valyala/fasthttp"
)
Expand Down Expand Up @@ -59,6 +61,18 @@ type Client struct {
// NoDefaultUserAgentHeader when set to true, causes the default
// User-Agent header to be excluded from the Request.
NoDefaultUserAgentHeader bool

// When set by an external client of Fiber it will use the provided implementation of a
// JSONMarshal
//
// Allowing for flexibility in using another json library for encoding
JSONEncoder utils.JSONMarshal

// When set by an external client of Fiber it will use the provided implementation of a
// JSONUnmarshal
//
// Allowing for flexibility in using another json library for decoding
JSONDecoder utils.JSONUnmarshal
}

// Get returns a agent with http method GET.
Expand Down Expand Up @@ -116,6 +130,8 @@ func (c *Client) createAgent(method, url string) *Agent {

a.Name = c.UserAgent
a.NoDefaultUserAgentHeader = c.NoDefaultUserAgentHeader
a.jsonDecoder = c.JSONDecoder
a.jsonEncoder = c.JSONEncoder

if err := a.Parse(); err != nil {
a.errs = append(a.errs, err)
Expand All @@ -135,6 +151,8 @@ type Agent struct {
formFiles []*FormFile
debugWriter io.Writer
mw multipartWriter
jsonEncoder utils.JSONMarshal
jsonDecoder utils.JSONUnmarshal
maxRedirectsCount int
boundary string
Name string
Expand Down Expand Up @@ -450,9 +468,13 @@ func (a *Agent) Request(req *Request) *Agent {

// JSON sends a JSON request.
func (a *Agent) JSON(v interface{}) *Agent {
if a.jsonEncoder == nil {
a.jsonEncoder = json.Marshal
}

a.req.Header.SetContentType(MIMEApplicationJSON)

if body, err := json.Marshal(v); err != nil {
if body, err := a.jsonEncoder(v); err != nil {
a.errs = append(a.errs, err)
} else {
a.req.SetBody(body)
Expand Down Expand Up @@ -658,6 +680,20 @@ func (a *Agent) MaxRedirectsCount(count int) *Agent {
return a
}

// JSONEncoder sets custom json encoder.
func (a *Agent) JSONEncoder(jsonEncoder utils.JSONMarshal) *Agent {
a.jsonEncoder = jsonEncoder

return a
}

// JSONDecoder sets custom json decoder.
func (a *Agent) JSONDecoder(jsonDecoder utils.JSONUnmarshal) *Agent {
a.jsonDecoder = jsonDecoder

return a
}

/************************** End Agent Setting **************************/

// Bytes returns the status code, bytes body and errors of url.
Expand Down Expand Up @@ -738,9 +774,13 @@ func (a *Agent) String(resp ...*Response) (int, string, []error) {
// Struct returns the status code, bytes body and errors of url.
// And bytes body will be unmarshalled to given v.
func (a *Agent) Struct(v interface{}, resp ...*Response) (code int, body []byte, errs []error) {
if a.jsonDecoder == nil {
a.jsonDecoder = json.Unmarshal
}

code, body, errs = a.Bytes(resp...)

if err := json.Unmarshal(body, v); err != nil {
if err := a.jsonDecoder(body, v); err != nil {
errs = append(errs, err)
}

Expand Down
6 changes: 5 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"testing"
"time"

"github.com/gofiber/fiber/v2/internal/encoding/json"

"github.com/gofiber/fiber/v2/utils"
"github.com/valyala/fasthttp/fasthttputil"
)
Expand Down Expand Up @@ -532,6 +534,7 @@ func Test_Client_Agent_Json(t *testing.T) {

func Test_Client_Agent_Json_Error(t *testing.T) {
a := Get("http://example.com").
JSONEncoder(json.Marshal).
JSON(complex(1, 1))

_, body, errs := a.String()
Expand Down Expand Up @@ -947,7 +950,8 @@ func Test_Client_Agent_Struct(t *testing.T) {

var d data

code, body, errs := a.Struct(&d)
code, body, errs := a.JSONDecoder(json.Unmarshal).
Struct(&d)

utils.AssertEqual(t, StatusOK, code)
utils.AssertEqual(t, `{"success"`, string(body))
Expand Down
9 changes: 9 additions & 0 deletions utils/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package utils

// JSONMarshal returns the JSON encoding of v.
type JSONMarshal func(v interface{}) ([]byte, error)

// JSONUnmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v. If v is nil or not a pointer,
// Unmarshal returns an InvalidUnmarshalError.
type JSONUnmarshal func(data []byte, v interface{}) error
5 changes: 0 additions & 5 deletions utils/json_marshal.go

This file was deleted.

26 changes: 0 additions & 26 deletions utils/json_marshal_test.go

This file was deleted.

41 changes: 41 additions & 0 deletions utils/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package utils

import (
"encoding/json"
"testing"
)

type sampleStructure struct {
ImportantString string `json:"important_string"`
}

func Test_DefaultJSONEncoder(t *testing.T) {
t.Parallel()

var (
ss = &sampleStructure{
ImportantString: "Hello World",
}
importantString = `{"important_string":"Hello World"}`
jsonEncoder JSONMarshal = json.Marshal
)

raw, err := jsonEncoder(ss)
AssertEqual(t, err, nil)

AssertEqual(t, string(raw), importantString)
}

func Test_DefaultJSONDecoder(t *testing.T) {
t.Parallel()

var (
ss sampleStructure
importantString = []byte(`{"important_string":"Hello World"}`)
jsonDecoder JSONUnmarshal = json.Unmarshal
)

err := jsonDecoder(importantString, &ss)
AssertEqual(t, err, nil)
AssertEqual(t, "Hello World", ss.ImportantString)
}

0 comments on commit c34ca83

Please sign in to comment.