Skip to content

Commit

Permalink
feat: register path directive by default, but support encoding only
Browse files Browse the repository at this point in the history
  • Loading branch information
ggicci committed Dec 31, 2023
1 parent 923ff2f commit 40647db
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
15 changes: 7 additions & 8 deletions core/directive.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ func init() {
RegisterDirective("body", &DirectiveBody{})
RegisterDirective("required", &DirectiveRequired{})
RegisterDirective("default", &DirectiveDefault{})
registerDirective("nonzero", &DirectiveNonzero{})
RegisterDirective("nonzero", &DirectiveNonzero{})
registerDirective("path", defaultPathDirective)

// decoder is a special executor which does nothing, but is an indicator of
// overriding the decoder for a specific field.
registerDirective("decoder", noopDirective)
registerDirective("coder", noopDirective)
}

var (
Expand All @@ -41,13 +47,6 @@ type DirectiveExecutor interface {
Decode(*DirectiveRuntime) error
}

func init() {
// decoder is a special executor which does nothing, but is an indicator of
// overriding the decoder for a specific field.
registerDirective("decoder", noopDirective)
registerDirective("coder", noopDirective)
}

// RegisterDirective registers a DirectiveExecutor with the given directive name. The
// directive should be able to both extract the value from the HTTP request and build
// the HTTP request from the value. The Decode API is used to decode data from the HTTP
Expand Down
10 changes: 10 additions & 0 deletions core/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package core

import "errors"

type DirectivePath struct {
decode func(*DirectiveRuntime) error
}
Expand All @@ -24,3 +26,11 @@ func (*DirectivePath) Encode(rtm *DirectiveRuntime) error {
}
return encoder.Execute(rtm)
}

// defaultPathDirective is the default path directive, which only supports encoding,
// while the decoding function is not implmented. Because the path decoding depends on the
// routing framework, it should be implemented in the integration package.
// See integration/gochi.go and integration/gorilla.go for examples.
var defaultPathDirective = NewDirectivePath(func(rtm *DirectiveRuntime) error {
return errors.New("unimplemented path decoding function")
})
15 changes: 13 additions & 2 deletions core/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,20 @@ func TestDirectivePath_Decode(t *testing.T) {
assert.ErrorIs(t, pathDirective.Decode(nil), assert.AnError)
}

func TestDirectivePath_NewRequest(t *testing.T) {
func TestDirectivePath_ErrDefaultPathDecodingIsUnimplemented(t *testing.T) {
type GetProfileRequest struct {
Username string `in:"path=username"`
}

co, err := New(GetProfileRequest{})
assert.NoError(t, err)
req, _ := http.NewRequest("GET", "/users/ggicci", nil)
_, err = co.Decode(req)
assert.ErrorContains(t, err, "unimplemented path decoding function")
}

func TestDirectivePath_NewRequest_DefalutPathEncodingShouldWork(t *testing.T) {
assert := assert.New(t)
RegisterDirective("path", NewDirectivePath(myCustomPathDecode))
type Repository struct {
Name string `json:"name"`
Visibility string `json:"visibility"` // public, private, internal
Expand Down
1 change: 1 addition & 0 deletions integration/gochi.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func UseGochiURLParam(name string, fn GochiURLParamFunc) {
core.RegisterDirective(
name,
core.NewDirectivePath((&gochiURLParamExtractor{URLParam: fn}).Execute),
true,
)
}

Expand Down
1 change: 1 addition & 0 deletions integration/gorilla.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func UseGorillaMux(name string, fnVars GorillaMuxVarsFunc) {
core.RegisterDirective(
name,
core.NewDirectivePath((&gorillaMuxVarsExtractor{Vars: fnVars}).Execute),
true,
)
}

Expand Down

0 comments on commit 40647db

Please sign in to comment.