Skip to content

Commit

Permalink
add StringToURLHookFunc decode hook
Browse files Browse the repository at this point in the history
  • Loading branch information
aix3 committed Jul 26, 2023
1 parent bf980b3 commit 12c4d5b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
21 changes: 21 additions & 0 deletions decode_hooks.go
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
"net/url"
"reflect"
"strconv"
"strings"
Expand Down Expand Up @@ -201,6 +202,26 @@ func StringToTimeHookFunc(layout string) DecodeHookFunc {
}
}

// StringToURLHookFunc returns a DecodeHookFunc that converts
// strings to url.URL.
func StringToURLHookFunc() DecodeHookFunc {
return func(
f reflect.Type,
t reflect.Type,
data interface{}) (interface{}, error) {
if f.Kind() != reflect.String {
return data, nil
}
if t != reflect.TypeOf(url.URL{}) {
return data, nil
}

// Convert it by parsing
u, err := url.Parse(data.(string))
return *u, err
}
}

// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
// the decoder.
//
Expand Down
40 changes: 40 additions & 0 deletions decode_hooks_test.go
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"math/big"
"net"
"net/url"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -361,6 +362,45 @@ func TestStringToIPNetHookFunc(t *testing.T) {
}
}

func TestStringToURLHookFunc(t *testing.T) {
f := StringToURLHookFunc()

urlValue := reflect.ValueOf(url.URL{})
strValue := reflect.ValueOf("")

cases := []struct {
f, t reflect.Value
result interface{}
err bool
}{
{reflect.ValueOf("https://u:p@example.com?p=1"), urlValue,
url.URL{
Scheme: "https",
Host: "example.com",
User: url.UserPassword("u", "p"),
RawQuery: "p=1",
}, false},
{reflect.ValueOf("https://example.com"), strValue, "https://example.com", false},
{strValue, urlValue, url.URL{}, false},
{reflect.ValueOf("example"), urlValue,
url.URL{
Path: "example",
}, false},
}

for i, tc := range cases {
actual, err := DecodeHookExec(f, tc.f, tc.t)
if tc.err != (err != nil) {
t.Fatalf("case %d: expected err %#v", i, tc.err)
}
if !reflect.DeepEqual(actual, tc.result) {
t.Fatalf(
"case %d: expected %#v, got %#v",
i, tc.result, actual)
}
}
}

func TestWeaklyTypedHook(t *testing.T) {
var f DecodeHookFunc = WeaklyTypedHook

Expand Down

0 comments on commit 12c4d5b

Please sign in to comment.