diff options
| author | Shulhan <ms@kilabit.info> | 2024-01-25 00:42:16 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2024-01-25 00:42:16 +0700 |
| commit | a055c87a24417dbc6760224ad9dcfb204751e702 (patch) | |
| tree | 251080edd973eef33e0fa6dbd4ce6f2cb78ac552 | |
| parent | 2c90844a04228ec7ba810689c68289748f0ccdfd (diff) | |
| download | pakakeh.go-a055c87a24417dbc6760224ad9dcfb204751e702.tar.xz | |
lib/path: add method Set to Route
The Set method set or replace the key's value in path with parameter val.
If the key exist it will return true; otherwise it will return false.
This changes remove unnecessary field key in routeNode and optimize
the String method using [strings.Builder].
| -rw-r--r-- | lib/path/route.go | 52 | ||||
| -rw-r--r-- | lib/path/route_example_test.go | 32 | ||||
| -rw-r--r-- | lib/path/route_node.go | 2 | ||||
| -rw-r--r-- | lib/path/route_test.go | 4 |
4 files changed, 77 insertions, 13 deletions
diff --git a/lib/path/route.go b/lib/path/route.go index 7548d056..1cf9d419 100644 --- a/lib/path/route.go +++ b/lib/path/route.go @@ -53,12 +53,12 @@ func NewRoute(rpath string) (rute *Route, err error) { var node = &routeNode{} if subpath[0] == ':' { - node.key = strings.TrimSpace(subpath[1:]) - if len(node.key) == 0 { + node.name = strings.TrimSpace(subpath[1:]) + if len(node.name) == 0 { return nil, ErrPathKeyEmpty } - if rute.isKeyExist(node.key) { + if rute.isKeyExist(node.name) { return nil, ErrPathKeyDuplicate } @@ -87,7 +87,7 @@ func (rute *Route) isKeyExist(key string) bool { if !node.isKey { continue } - if node.key == key { + if node.name == key { return true } } @@ -121,7 +121,7 @@ func (rute *Route) Parse(rpath string) (vals map[string]string, ok bool) { for x, node = range rute.nodes { if node.isKey { - vals[node.key] = paths[x] + vals[node.name] = paths[x] } else if paths[x] != node.name { return nil, false } @@ -130,17 +130,49 @@ func (rute *Route) Parse(rpath string) (vals map[string]string, ok bool) { return vals, true } +// Set or replace the key's value in path with parameter val. +// If the key exist it will return true; otherwise it will return false. +func (rute *Route) Set(key, val string) bool { + key = strings.TrimSpace(key) + if len(key) == 0 { + return false + } + key = strings.ToLower(key) + + var node *routeNode + for _, node = range rute.nodes { + if !node.isKey { + continue + } + if node.name == key { + node.val = val + return true + } + } + return false +} + // String generate a clean path without any white spaces and single "/" // between sub-path. +// If the key has been [Route.Set], the sub-path will be replaced with its +// value, otherwise it will returned as ":<key>". func (rute *Route) String() (path string) { - var node *routeNode + var ( + node *routeNode + pb strings.Builder + ) for _, node = range rute.nodes { - path += `/` + pb.WriteByte('/') if node.isKey { - path += `:` + node.key + if len(node.val) == 0 { + pb.WriteByte(':') + pb.WriteString(node.name) + } else { + pb.WriteString(node.val) + } } else { - path += node.name + pb.WriteString(node.name) } } - return path + return pb.String() } diff --git a/lib/path/route_example_test.go b/lib/path/route_example_test.go new file mode 100644 index 00000000..d97603c1 --- /dev/null +++ b/lib/path/route_example_test.go @@ -0,0 +1,32 @@ +// Copyright 2024, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package path_test + +import ( + "fmt" + "log" + + libpath "github.com/shuLhan/share/lib/path" +) + +func ExampleRoute_Set() { + var ( + rute *libpath.Route + err error + ) + rute, err = libpath.NewRoute(`/:user/:repo`) + if err != nil { + log.Fatal(err) + } + + rute.Set(`user`, `shuLhan`) + fmt.Println(rute) + + rute.Set(`repo`, `share`) + fmt.Println(rute) + // Output: + // /shuLhan/:repo + // /shuLhan/share +} diff --git a/lib/path/route_node.go b/lib/path/route_node.go index dd1b06b0..b89ab24e 100644 --- a/lib/path/route_node.go +++ b/lib/path/route_node.go @@ -10,7 +10,7 @@ package path // A sub-path that start with colon ":" is a key; otherwise its normal // sub-path. type routeNode struct { - key string name string + val string isKey bool } diff --git a/lib/path/route_test.go b/lib/path/route_test.go index c0c7ba01..bd3bcbbb 100644 --- a/lib/path/route_test.go +++ b/lib/path/route_test.go @@ -46,10 +46,10 @@ func TestNewRoute(t *testing.T) { exp: &Route{ path: `/:user/:repo`, nodes: []*routeNode{{ - key: `user`, + name: `user`, isKey: true, }, { - key: `repo`, + name: `repo`, isKey: true, }}, nkey: 2, |
