From 2b31a6a970ed6523e0b218ca4f0042498bfdc987 Mon Sep 17 00:00:00 2001 From: surdeus Date: Thu, 30 May 2024 11:30:25 +0500 Subject: [PATCH] feat: more structured way to accesn urlencs builder. --- urlenc/build.go | 67 +++++++++++++++++++++++++++++++++----------- urlenc/build_test.go | 16 +++++++---- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/urlenc/build.go b/urlenc/build.go index 257fa31..f09c46b 100644 --- a/urlenc/build.go +++ b/urlenc/build.go @@ -1,14 +1,35 @@ package urlenc -import "strings" 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 Value V } -func (a Pair[V]) String() string { - return fmt.Sprintf("%s=%v", a.Name, a.Value) +func (value Value[V]) BuildQueryValues() Values { + 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 { @@ -16,21 +37,35 @@ type Array[V any] struct { Values []V } -func (a Array[V]) String() string { - var b strings.Builder +func (a Array[V]) BuildQueryValues() Values { + values := Values{} for i, v := range a.Values { - fmt.Fprintf(&b, "%s[%d]=%v", a.Name, i, v) - if i < len(a.Values) - 1 { - fmt.Fprint(&b, "&") - } + values.Add( + fmt.Sprintf("%s[%d]", a.Name, i), + fmt.Sprintf("%v", v), + ) } - return b.String() + return values } -func Join(values ...any) string { - vs := make([]string, len(values)) - for i, v := range values { - vs[i] = fmt.Sprintf("%s", v) +func (a Array[V]) String() string { + unesc, err := url.QueryUnescape( + a.BuildQueryValues().Encode(), + ) + 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 } diff --git a/urlenc/build_test.go b/urlenc/build_test.go index d2cd85e..bb4d183 100644 --- a/urlenc/build_test.go +++ b/urlenc/build_test.go @@ -4,20 +4,24 @@ import "testing" import "log" func TestArray(t *testing.T) { - log.Printf("Array{...}: %s\n", Array[int]{ - Name: "id", - Values: []int{123, 456, 789}, - }) + log.Printf( + "Array{...}: %s\n", + Array[int]{ + Name: "id", + Values: []int{123, 456, 789}, + }, + ) } func TestJoin(t *testing.T) { log.Printf( + "Join(...): %s", Join( Array[int]{ "id", []int{123, 456, 789}, }, - Pair[int]{"somename", 25}, - ), + Value[string]{"somename", "value with '='"}, + ).Encode(), ) }