summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2024-01-25 00:42:16 +0700
committerShulhan <ms@kilabit.info>2024-01-25 00:42:16 +0700
commita055c87a24417dbc6760224ad9dcfb204751e702 (patch)
tree251080edd973eef33e0fa6dbd4ce6f2cb78ac552
parent2c90844a04228ec7ba810689c68289748f0ccdfd (diff)
downloadpakakeh.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.go52
-rw-r--r--lib/path/route_example_test.go32
-rw-r--r--lib/path/route_node.go2
-rw-r--r--lib/path/route_test.go4
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,