diff --git a/core/directive.go b/core/directive.go index 22fcbf7..fa82fc3 100644 --- a/core/directive.go +++ b/core/directive.go @@ -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 ( @@ -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 diff --git a/core/path.go b/core/path.go index 1a0f156..0092637 100644 --- a/core/path.go +++ b/core/path.go @@ -3,6 +3,8 @@ package core +import "errors" + type DirectivePath struct { decode func(*DirectiveRuntime) error } @@ -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") +}) diff --git a/core/path_test.go b/core/path_test.go index 229e313..b01a377 100644 --- a/core/path_test.go +++ b/core/path_test.go @@ -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 diff --git a/integration/gochi.go b/integration/gochi.go index 9447ef8..d418f9d 100644 --- a/integration/gochi.go +++ b/integration/gochi.go @@ -28,6 +28,7 @@ func UseGochiURLParam(name string, fn GochiURLParamFunc) { core.RegisterDirective( name, core.NewDirectivePath((&gochiURLParamExtractor{URLParam: fn}).Execute), + true, ) } diff --git a/integration/gorilla.go b/integration/gorilla.go index a85258b..957f608 100644 --- a/integration/gorilla.go +++ b/integration/gorilla.go @@ -27,6 +27,7 @@ func UseGorillaMux(name string, fnVars GorillaMuxVarsFunc) { core.RegisterDirective( name, core.NewDirectivePath((&gorillaMuxVarsExtractor{Vars: fnVars}).Execute), + true, ) }