From 21e48eb7a908879c835824d5b3b9edf0dda5c0ff Mon Sep 17 00:00:00 2001 From: marrow16 Date: Wed, 19 Jul 2023 19:22:39 +0100 Subject: [PATCH] Remove patterns Added `Template()` method (with option to remove patterns) --- path_part.go | 12 ++++++++++++ template.go | 18 ++++++++++++++++++ template_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/path_part.go b/path_part.go index efd3505..401b87e 100644 --- a/path_part.go +++ b/path_part.go @@ -171,6 +171,18 @@ func (pt *pathPart) getVars(vars []PathVar, namePosns map[string]int) []PathVar return vars } +func (pt *pathPart) buildNoPattern(builder *strings.Builder) { + if pt.fixed { + builder.WriteString(pt.fixedValue) + } else if len(pt.subParts) > 0 { + for _, sp := range pt.subParts { + sp.buildNoPattern(builder) + } + } else { + builder.WriteString("{" + pt.name + "}") + } +} + type positionsTracker struct { vars PathVars varPosition int diff --git a/template.go b/template.go index 478d7c7..c016a96 100644 --- a/template.go +++ b/template.go @@ -68,6 +68,8 @@ type Template interface { Vars() []PathVar // OriginalTemplate returns the original (or generated) path template string OriginalTemplate() string + // Template returns the template (optionally with any path var patterns removed) + Template(removePatterns bool) string } type template struct { @@ -316,6 +318,22 @@ func (t *template) OriginalTemplate() string { return t.originalTemplate } +// Template returns the template (optionally with any path var patterns removed) +func (t *template) Template(removePatterns bool) string { + if removePatterns { + var builder strings.Builder + if len(t.pathParts) == 0 { + builder.WriteString("/") + } + for _, pt := range t.pathParts { + builder.WriteString("/") + pt.buildNoPattern(&builder) + } + return builder.String() + } + return t.originalTemplate +} + func separatePathOptions(options []interface{}) (host HostOption, params QueryParamsOption, headers HeadersOption, varMatches varMatchOptions) { for _, intf := range options { if h, ok := intf.(HostOption); ok { diff --git a/template_test.go b/template_test.go index 6fde247..caf23e2 100644 --- a/template_test.go +++ b/template_test.go @@ -2,6 +2,7 @@ package urit import ( "fmt" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net/http" "net/url" @@ -607,6 +608,50 @@ func TestTemplate_Vars(t *testing.T) { } } +func TestTemplate_Template(t *testing.T) { + testCases := []struct { + path string + expect string + }{ + { + path: "/", + expect: "/", + }, + { + path: "/foo/bar/baz", + expect: "/foo/bar/baz", + }, + { + path: "/foo/{fooid}/bar/{barid}/baz/{bazid}", + expect: "/foo/{fooid}/bar/{barid}/baz/{bazid}", + }, + { + path: "/foo/{fooid: [a-z]*}/bar/{barid: [a-z]*}/baz/{bazid: [a-z]*}", + expect: "/foo/{fooid}/bar/{barid}/baz/{bazid}", + }, + { + path: "/foo/{fooA}-{fooB}", + expect: "/foo/{fooA}-{fooB}", + }, + { + path: "/foo/{fooA: [a-z]*}-{fooB: [a-z]*}", + expect: "/foo/{fooA}-{fooB}", + }, + { + path: "/foo/{fooA: [a-z]*}-{fooB: [a-z]*}/bar/{barA}-{barB}", + expect: "/foo/{fooA}-{fooB}/bar/{barA}-{barB}", + }, + } + for i, tc := range testCases { + t.Run(fmt.Sprintf("[%d]", i+1), func(t *testing.T) { + tmp, err := NewTemplate(tc.path) + assert.NoError(t, err) + assert.Equal(t, tc.expect, tmp.Template(true)) + assert.Equal(t, tc.path, tmp.Template(false)) + }) + } +} + type uuidChecker struct { }