Skip to content

Commit 3e7505c

Browse files
joeybloggsjoeybloggs
authored andcommitted
Add usage of DecodeCustomTypeFunc within map keys also.
1 parent d77a15c commit 3e7505c

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package form
22
============
33
<img align="right" src="https://raw.githubusercontent.com/go-playground/form/master/logo.jpg">
4-
![Project status](https://img.shields.io/badge/version-1.2.1-green.svg)
4+
![Project status](https://img.shields.io/badge/version-1.3.0-green.svg)
55
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/form/branches/master/badge.svg)](https://semaphoreci.com/joeybloggs/form)
66
[![Coverage Status](https://coveralls.io/repos/github/go-playground/form/badge.svg?branch=master)](https://coveralls.io/github/go-playground/form?branch=master)
77
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/form)](https://goreportcard.com/report/github.com/go-playground/form)

decoder.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,19 @@ func (d *decoder) getMapKey(key string, current reflect.Value, namespace string)
448448

449449
v, kind := ExtractType(current)
450450

451+
if d.d.customTypeFuncs != nil {
452+
if cf, ok := d.d.customTypeFuncs[v.Type()]; ok {
453+
val, er := cf([]string{key})
454+
if er != nil {
455+
err = er
456+
return
457+
}
458+
459+
v.Set(reflect.ValueOf(val))
460+
return
461+
}
462+
}
463+
451464
switch kind {
452465
case reflect.Interface:
453466
v.Set(reflect.ValueOf(key))

form.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ var (
2020
timeType = reflect.TypeOf(time.Time{})
2121
)
2222

23-
// CustomTypeFunc allows for registering/overriding types to be parsed.
24-
type CustomTypeFunc func([]string) (interface{}, error)
23+
// DecodeCustomTypeFunc allows for registering/overriding types to be parsed.
24+
type DecodeCustomTypeFunc func([]string) (interface{}, error)
2525

2626
// DecodeErrors is a map of errors encountered during form decoding
2727
type DecodeErrors map[string]error
@@ -62,7 +62,7 @@ type dataMap map[string]*recursiveData
6262
type Decoder struct {
6363
tagName string
6464
structCache structCacheMap
65-
customTypeFuncs map[reflect.Type]CustomTypeFunc
65+
customTypeFuncs map[reflect.Type]DecodeCustomTypeFunc
6666
}
6767

6868
// NewDecoder creates a new decoder instance with sane defaults
@@ -79,12 +79,13 @@ func (d *Decoder) SetTagName(tagName string) {
7979
d.tagName = tagName
8080
}
8181

82-
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
82+
// RegisterCustomTypeFunc registers a DecodeCustomTypeFunc against a number of types; the function
83+
// will also be used within the map key section.
8384
// NOTE: this method is not thread-safe it is intended that these all be registered prior to any parsing
84-
func (d *Decoder) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
85+
func (d *Decoder) RegisterCustomTypeFunc(fn DecodeCustomTypeFunc, types ...interface{}) {
8586

8687
if d.customTypeFuncs == nil {
87-
d.customTypeFuncs = map[reflect.Type]CustomTypeFunc{}
88+
d.customTypeFuncs = map[reflect.Type]DecodeCustomTypeFunc{}
8889
}
8990

9091
for _, t := range types {

form_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ func TestStruct(t *testing.T) {
518518
BigEnoughNumberedArray []string
519519
IfaceNonNil interface{}
520520
IfaceInvalid interface{}
521+
TimeMapKey map[time.Time]string
521522
}
522523

523524
values := url.Values{
@@ -539,6 +540,7 @@ func TestStruct(t *testing.T) {
539540
"TooSmallNumberedArray[2]": []string{"2"},
540541
"TooSmallCapOKNumberedArray[2]": []string{"2"},
541542
"BigEnoughNumberedArray[2]": []string{"1"},
543+
"TimeMapKey[2016-01-02]": []string{"time"},
542544
}
543545

544546
var test TestStruct
@@ -604,6 +606,12 @@ func TestStruct(t *testing.T) {
604606
Equal(t, test.Time.Equal(tm), true)
605607
Equal(t, (*test.TimePtr).Equal(tm), true)
606608

609+
NotEqual(t, test.TimeMapKey, nil)
610+
Equal(t, len(test.TimeMapKey), 1)
611+
612+
_, ok := test.TimeMapKey[tm]
613+
Equal(t, ok, true)
614+
607615
s := struct {
608616
Value string
609617
Ignore string `form:"-"`
@@ -655,6 +663,7 @@ func TestErrors(t *testing.T) {
655663
MapBadBoolKey map[bool]bool
656664
MapBadKeyType map[complex64]int
657665
BadArrayValue []int
666+
BadMapKey map[time.Time]string
658667
}
659668

660669
values := url.Values{
@@ -670,6 +679,7 @@ func TestErrors(t *testing.T) {
670679
"MapBadBoolKey[uh-huh]": []string{"true"},
671680
"MapBadKeyType[1.4]": []string{"5"},
672681
"BadArrayValue[0]": []string{"badintval"},
682+
"BadMapKey[badtime]": []string{"badtime"},
673683
}
674684

675685
var test TestError
@@ -678,6 +688,7 @@ func TestErrors(t *testing.T) {
678688
decoder.RegisterCustomTypeFunc(func(vals []string) (interface{}, error) {
679689
return nil, errors.New("Bad Type Conversion")
680690
}, "")
691+
681692
errs := decoder.Decode(&test, values)
682693
NotEqual(t, errs, nil)
683694

@@ -720,6 +731,29 @@ func TestErrors(t *testing.T) {
720731

721732
k = err["BadArrayValue[0]"]
722733
Equal(t, k.Error(), "Invalid Integer Value 'badintval' Type 'int' Namespace 'BadArrayValue[0]'")
734+
735+
type TestError2 struct {
736+
BadMapKey map[time.Time]string
737+
}
738+
739+
values2 := url.Values{
740+
"BadMapKey[badtime]": []string{"badtime"},
741+
}
742+
743+
var test2 TestError2
744+
decoder2 := NewDecoder()
745+
decoder2.RegisterCustomTypeFunc(func(vals []string) (interface{}, error) {
746+
return time.Parse("2006-01-02", vals[0])
747+
}, time.Time{})
748+
749+
errs = decoder2.Decode(&test2, values2)
750+
NotEqual(t, errs, nil)
751+
752+
e = errs.Error()
753+
NotEqual(t, e, "")
754+
755+
k = err["BadMapKey"]
756+
Equal(t, k.Error(), "Unsupported Map Key 'badtime', Type 'time.Time' Namespace 'BadMapKey'")
723757
}
724758

725759
func TestPanics(t *testing.T) {

0 commit comments

Comments
 (0)