Skip to content

Commit 8e98da8

Browse files
authored
Merge pull request #34 from monoculum/disable-opt-unmarshal-text
option to disable UnmarshalText interface: fix #33
2 parents d7a8fbd + 33ae2cf commit 8e98da8

File tree

2 files changed

+63
-10
lines changed

2 files changed

+63
-10
lines changed

formam.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ type DecoderOptions struct {
8181
// Prefer UnmarshalText over custom types.
8282
PrefUnmarshalText bool
8383

84+
// Disable UnmarshalText interface
85+
DisableUnmarshalText bool
86+
8487
// Ignore unknown form fields. By default unknown fields are an error
8588
// (although all valid keys will still be decoded).
8689
IgnoreUnknownKeys bool
@@ -371,20 +374,27 @@ func (dec *Decoder) traverseInMap(byField bool) {
371374

372375
// decode sets the value in the field
373376
func (dec *Decoder) decode() error {
374-
// check if has UnmarshalText method or a custom function to decode it
375-
if dec.opts.PrefUnmarshalText {
376-
if ok, err := dec.isUnmarshalText(dec.curr); ok || err != nil {
377-
return err
378-
}
377+
// if DisableUnmarshalText is true then only use customType if available
378+
if dec.opts.DisableUnmarshalText {
379379
if ok, err := dec.isCustomType(); ok || err != nil {
380380
return err
381381
}
382382
} else {
383-
if ok, err := dec.isCustomType(); ok || err != nil {
384-
return err
385-
}
386-
if ok, err := dec.isUnmarshalText(dec.curr); ok || err != nil {
387-
return err
383+
// check if has UnmarshalText method or a custom function to decode it
384+
if dec.opts.PrefUnmarshalText {
385+
if ok, err := dec.isUnmarshalText(dec.curr); ok || err != nil {
386+
return err
387+
}
388+
if ok, err := dec.isCustomType(); ok || err != nil {
389+
return err
390+
}
391+
} else {
392+
if ok, err := dec.isCustomType(); ok || err != nil {
393+
return err
394+
}
395+
if ok, err := dec.isUnmarshalText(dec.curr); ok || err != nil {
396+
return err
397+
}
388398
}
389399
}
390400

@@ -654,6 +664,8 @@ var (
654664

655665
// isUnmarshalText returns a boolean and error. The boolean is true if the
656666
// field's type implements TextUnmarshaler, and false if not.
667+
// If the field implements TextUnmarshaler, then it is used to decode the value
668+
// in the field.
657669
func (dec *Decoder) isUnmarshalText(v reflect.Value) (bool, error) {
658670
// check if implements the interface
659671
m, ok := v.Interface().(encoding.TextUnmarshaler)

formam_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,47 @@ func TestArrayLength(t *testing.T) {
971971
}
972972
}
973973

974+
type StringWithUnmarshalText string
975+
976+
func (s *StringWithUnmarshalText) UnmarshalText(data []byte) error {
977+
*s = "string by UnmarshalText"
978+
return nil
979+
}
980+
981+
func TestEnableUnmarshalText(t *testing.T) {
982+
s := struct {
983+
Text StringWithUnmarshalText
984+
}{}
985+
vals := url.Values{
986+
"Text": []string{"string by form"},
987+
}
988+
dec := formam.NewDecoder(&formam.DecoderOptions{})
989+
if err := dec.Decode(vals, &s); err != nil {
990+
t.Fatalf("error when decode %s", err)
991+
}
992+
if s.Text != "string by UnmarshalText" {
993+
t.Errorf("the UnmarshalText hasn't been called")
994+
}
995+
}
996+
997+
func TestDisableUnmarshalText(t *testing.T) {
998+
s := struct {
999+
Text StringWithUnmarshalText
1000+
}{}
1001+
vals := url.Values{
1002+
"Text": []string{"string by form"},
1003+
}
1004+
dec := formam.NewDecoder(&formam.DecoderOptions{
1005+
DisableUnmarshalText: true,
1006+
})
1007+
if err := dec.Decode(vals, &s); err != nil {
1008+
t.Fatalf("error when decode %s", err)
1009+
}
1010+
if s.Text != "string by form" {
1011+
t.Errorf("the UnmarshalText has been called")
1012+
}
1013+
}
1014+
9741015
// errorContains checks if the error message in out contains the text in
9751016
// want.
9761017
//

0 commit comments

Comments
 (0)