feat: more structured way to accesn urlencs builder.

This commit is contained in:
Andrey Parhomenko 2024-05-30 11:30:25 +05:00
parent fabcb6fd49
commit 2b31a6a970
2 changed files with 61 additions and 22 deletions

View file

@ -1,14 +1,35 @@
package urlenc package urlenc
import "strings"
import "fmt" import "fmt"
import "net/url"
type Pair[V any] struct { type Values = url.Values
type Builder interface {
BuildQueryValues() Values
}
type Value[V any] struct {
Name string Name string
Value V Value V
} }
func (a Pair[V]) String() string { func (value Value[V]) BuildQueryValues() Values {
return fmt.Sprintf("%s=%v", a.Name, a.Value) values := Values{}
values.Add(
value.Name,
fmt.Sprintf("%v", value.Value),
)
return values
}
func (value Value[V]) String() string {
unesc, err := url.QueryUnescape(
value.BuildQueryValues().Encode(),
)
if err != nil {
panic(err)
}
return unesc
} }
type Array[V any] struct { type Array[V any] struct {
@ -16,21 +37,35 @@ type Array[V any] struct {
Values []V Values []V
} }
func (a Array[V]) String() string { func (a Array[V]) BuildQueryValues() Values {
var b strings.Builder values := Values{}
for i, v := range a.Values { for i, v := range a.Values {
fmt.Fprintf(&b, "%s[%d]=%v", a.Name, i, v) values.Add(
if i < len(a.Values) - 1 { fmt.Sprintf("%s[%d]", a.Name, i),
fmt.Fprint(&b, "&") fmt.Sprintf("%v", v),
} )
} }
return b.String() return values
} }
func Join(values ...any) string { func (a Array[V]) String() string {
vs := make([]string, len(values)) unesc, err := url.QueryUnescape(
for i, v := range values { a.BuildQueryValues().Encode(),
vs[i] = fmt.Sprintf("%s", v) )
if err != nil {
panic(err)
} }
return strings.Join(vs, "&") return unesc
}
func Join(builders ...Builder) Values {
ret := Values{}
for _, builder := range builders {
for k, v := range builder.BuildQueryValues() {
for _, jv := range v {
ret.Add(k, jv)
}
}
}
return ret
} }

View file

@ -4,20 +4,24 @@ import "testing"
import "log" import "log"
func TestArray(t *testing.T) { func TestArray(t *testing.T) {
log.Printf("Array{...}: %s\n", Array[int]{ log.Printf(
Name: "id", "Array{...}: %s\n",
Values: []int{123, 456, 789}, Array[int]{
}) Name: "id",
Values: []int{123, 456, 789},
},
)
} }
func TestJoin(t *testing.T) { func TestJoin(t *testing.T) {
log.Printf( log.Printf(
"Join(...): %s",
Join( Join(
Array[int]{ Array[int]{
"id", "id",
[]int{123, 456, 789}, []int{123, 456, 789},
}, },
Pair[int]{"somename", 25}, Value[string]{"somename", "value with '='"},
), ).Encode(),
) )
} }