Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 8712ebd

Browse files
committed
add StringToURLHookFunc decode hook
1 parent bf980b3 commit 8712ebd

2 files changed

Lines changed: 61 additions & 0 deletions

File tree

decode_hooks.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net"
8+
"net/url"
89
"reflect"
910
"strconv"
1011
"strings"
@@ -201,6 +202,26 @@ func StringToTimeHookFunc(layout string) DecodeHookFunc {
201202
}
202203
}
203204

205+
// StringToURLHookFunc returns a DecodeHookFunc that converts
206+
// strings to url.URL.
207+
func StringToURLHookFunc() DecodeHookFunc {
208+
return func(
209+
f reflect.Type,
210+
t reflect.Type,
211+
data interface{}) (interface{}, error) {
212+
if f.Kind() != reflect.String {
213+
return data, nil
214+
}
215+
if t != reflect.TypeOf(&url.URL{}) {
216+
return data, nil
217+
}
218+
219+
// Convert it by parsing
220+
u, err := url.Parse(data.(string))
221+
return u, err
222+
}
223+
}
224+
204225
// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to
205226
// the decoder.
206227
//

decode_hooks_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"math/big"
66
"net"
7+
"net/url"
78
"reflect"
89
"testing"
910
"time"
@@ -361,6 +362,45 @@ func TestStringToIPNetHookFunc(t *testing.T) {
361362
}
362363
}
363364

365+
func TestStringToURLHookFunc(t *testing.T) {
366+
f := StringToURLHookFunc()
367+
368+
urlValue := reflect.ValueOf(&url.URL{})
369+
strValue := reflect.ValueOf("")
370+
371+
cases := []struct {
372+
f, t reflect.Value
373+
result interface{}
374+
err bool
375+
}{
376+
{reflect.ValueOf("https://u:p@example.com?p=1"), urlValue,
377+
&url.URL{
378+
Scheme: "https",
379+
Host: "example.com",
380+
User: url.UserPassword("u", "p"),
381+
RawQuery: "p=1",
382+
}, false},
383+
{reflect.ValueOf("https://example.com"), strValue, "https://example.com", false},
384+
{strValue, urlValue, &url.URL{}, false},
385+
{reflect.ValueOf("example"), urlValue,
386+
&url.URL{
387+
Path: "example",
388+
}, false},
389+
}
390+
391+
for i, tc := range cases {
392+
actual, err := DecodeHookExec(f, tc.f, tc.t)
393+
if tc.err != (err != nil) {
394+
t.Fatalf("case %d: expected err %#v", i, tc.err)
395+
}
396+
if !reflect.DeepEqual(actual, tc.result) {
397+
t.Fatalf(
398+
"case %d: expected %#v, got %#v",
399+
i, tc.result, actual)
400+
}
401+
}
402+
}
403+
364404
func TestWeaklyTypedHook(t *testing.T) {
365405
var f DecodeHookFunc = WeaklyTypedHook
366406

0 commit comments

Comments
 (0)