@@ -106,7 +106,7 @@ func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix
106106 if f .typ .Kind () == reflect .Struct {
107107 err := d .checkRequired (f .typ , src , prefix + f .alias + "." )
108108 if err != nil {
109- if ! f .anon {
109+ if ! f .isAnonymous {
110110 return err
111111 }
112112 // check embedded parent field.
@@ -116,7 +116,7 @@ func (d *Decoder) checkRequired(t reflect.Type, src map[string][]string, prefix
116116 }
117117 }
118118 }
119- if f .required {
119+ if f .isRequired {
120120 key := f .alias
121121 if prefix != "" {
122122 key = prefix + key
@@ -185,7 +185,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
185185 // Get the converter early in case there is one for a slice type.
186186 conv := d .cache .converter (t )
187187 m := isTextUnmarshaler (v )
188- if conv == nil && t .Kind () == reflect .Slice && m .IsSlice {
188+ if conv == nil && t .Kind () == reflect .Slice && m .IsSliceElement {
189189 var items []reflect.Value
190190 elemT := t .Elem ()
191191 isPtrElem := elemT .Kind () == reflect .Ptr
@@ -211,7 +211,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
211211 }
212212 } else if m .IsValid {
213213 u := reflect .New (elemT )
214- if m .IsPtr {
214+ if m .IsSliceElementPtr {
215215 u = reflect .New (reflect .PtrTo (elemT ).Elem ())
216216 }
217217 if err := u .Interface ().(encoding.TextUnmarshaler ).UnmarshalText ([]byte (value )); err != nil {
@@ -222,7 +222,7 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
222222 Err : err ,
223223 }
224224 }
225- if m .IsPtr {
225+ if m .IsSliceElementPtr {
226226 items = append (items , u .Elem ().Addr ())
227227 } else if u .Kind () == reflect .Ptr {
228228 items = append (items , u .Elem ())
@@ -298,14 +298,27 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
298298 }
299299 }
300300 } else if m .IsValid {
301- // If the value implements the encoding.TextUnmarshaler interface
302- // apply UnmarshalText as the converter
303- if err := m .Unmarshaler .UnmarshalText ([]byte (val )); err != nil {
304- return ConversionError {
305- Key : path ,
306- Type : t ,
307- Index : - 1 ,
308- Err : err ,
301+ if m .IsPtr {
302+ u := reflect .New (v .Type ())
303+ if err := u .Interface ().(encoding.TextUnmarshaler ).UnmarshalText ([]byte (val )); err != nil {
304+ return ConversionError {
305+ Key : path ,
306+ Type : t ,
307+ Index : - 1 ,
308+ Err : err ,
309+ }
310+ }
311+ v .Set (reflect .Indirect (u ))
312+ } else {
313+ // If the value implements the encoding.TextUnmarshaler interface
314+ // apply UnmarshalText as the converter
315+ if err := m .Unmarshaler .UnmarshalText ([]byte (val )); err != nil {
316+ return ConversionError {
317+ Key : path ,
318+ Type : t ,
319+ Index : - 1 ,
320+ Err : err ,
321+ }
309322 }
310323 }
311324 } else if conv := builtinConverters [t .Kind ()]; conv != nil {
@@ -326,31 +339,36 @@ func (d *Decoder) decode(v reflect.Value, path string, parts []pathPart, values
326339}
327340
328341func isTextUnmarshaler (v reflect.Value ) unmarshaler {
329-
330342 // Create a new unmarshaller instance
331343 m := unmarshaler {}
332-
333- // As the UnmarshalText function should be applied
334- // to the pointer of the type, we convert the value to pointer.
335- if v .CanAddr () {
336- v = v .Addr ()
337- }
338344 if m .Unmarshaler , m .IsValid = v .Interface ().(encoding.TextUnmarshaler ); m .IsValid {
339345 return m
340346 }
347+ // As the UnmarshalText function should be applied to the pointer of the
348+ // type, we check that type to see if it implements the necessary
349+ // method.
350+ if m .Unmarshaler , m .IsValid = reflect .New (v .Type ()).Interface ().(encoding.TextUnmarshaler ); m .IsValid {
351+ m .IsPtr = true
352+ return m
353+ }
341354
342355 // if v is []T or *[]T create new T
343356 t := v .Type ()
344357 if t .Kind () == reflect .Ptr {
345358 t = t .Elem ()
346359 }
347360 if t .Kind () == reflect .Slice {
348- // if t is a pointer slice, check if it implements encoding.TextUnmarshaler
349- m .IsSlice = true
361+ // Check if the slice implements encoding.TextUnmarshaller
362+ if m .Unmarshaler , m .IsValid = v .Interface ().(encoding.TextUnmarshaler ); m .IsValid {
363+ return m
364+ }
365+ // If t is a pointer slice, check if its elements implement
366+ // encoding.TextUnmarshaler
367+ m .IsSliceElement = true
350368 if t = t .Elem (); t .Kind () == reflect .Ptr {
351369 t = reflect .PtrTo (t .Elem ())
352370 v = reflect .Zero (t )
353- m .IsPtr = true
371+ m .IsSliceElementPtr = true
354372 m .Unmarshaler , m .IsValid = v .Interface ().(encoding.TextUnmarshaler )
355373 return m
356374 }
@@ -365,9 +383,18 @@ func isTextUnmarshaler(v reflect.Value) unmarshaler {
365383// unmarshaller contains information about a TextUnmarshaler type
366384type unmarshaler struct {
367385 Unmarshaler encoding.TextUnmarshaler
368- IsSlice bool
369- IsPtr bool
370- IsValid bool
386+ // IsValid indicates whether the resolved type indicated by the other
387+ // flags implements the encoding.TextUnmarshaler interface.
388+ IsValid bool
389+ // IsPtr indicates that the resolved type is the pointer of the original
390+ // type.
391+ IsPtr bool
392+ // IsSliceElement indicates that the resolved type is a slice element of
393+ // the original type.
394+ IsSliceElement bool
395+ // IsSliceElementPtr indicates that the resolved type is a pointer to a
396+ // slice element of the original type.
397+ IsSliceElementPtr bool
371398}
372399
373400// Errors ---------------------------------------------------------------------
0 commit comments