@@ -169,8 +169,8 @@ func marshalStruct(value reflect.Value, opt *MarshalOpt) (string, error) {
169169 // If type is a struct
170170 // We loop through all struct field
171171 data := [][]string (nil )
172- for i := 0 ; i < value . NumField (); i ++ {
173- subData , err := marshal (value .Field ( i ), append (keys , value .Type ().Field ( i ).Name ))
172+ for _ , fieldIndex := range getStructFieldsIndex ( value ) {
173+ subData , err := marshal (value .FieldByIndex ( fieldIndex ), append (keys , value .Type ().FieldByIndex ( fieldIndex ).Name ))
174174 if err != nil {
175175 return nil , err
176176 }
@@ -207,6 +207,46 @@ func marshalStruct(value reflect.Value, opt *MarshalOpt) (string, error) {
207207 return strings .TrimSpace (buffer .String ()), nil
208208}
209209
210+ // getStructFieldsIndex will return a list of fieldIndex ([]int) sorted by their position in the Go struct.
211+ // This function will handle anonymous field and make sure that if a field is overwritten only the highest is returned.
212+ // You can use reflect GetFieldByIndex([]int) to get the correct field.
213+ func getStructFieldsIndex (v reflect.Value ) [][]int {
214+ // Using a map we make sure only the field with the highest order is returned for a given Name
215+ found := map [string ][]int {}
216+
217+ var recFunc func (v reflect.Value , parent []int )
218+ recFunc = func (v reflect.Value , parent []int ) {
219+ for i := 0 ; i < v .NumField (); i ++ {
220+ field := v .Type ().Field (i )
221+ // If a field is anonymous we start recursive call
222+ if field .Anonymous {
223+ recFunc (v .Field (i ), append (parent , i ))
224+ } else {
225+ // else we add the field in the found map
226+ found [field .Name ] = append (parent , i )
227+ }
228+ }
229+ }
230+ recFunc (v , []int (nil ))
231+
232+ result := [][]int (nil )
233+ for _ , value := range found {
234+ result = append (result , value )
235+ }
236+
237+ sort .Slice (result , func (i , j int ) bool {
238+ n := 0
239+ for n < len (result [i ]) && n < len (result [j ]) {
240+ if result [i ][n ] != result [j ][n ] {
241+ return result [i ][n ] < result [j ][n ]
242+ }
243+ }
244+ panic ("this can never happen" )
245+ })
246+
247+ return result
248+ }
249+
210250func marshalSlice (slice reflect.Value , opt * MarshalOpt ) (string , error ) {
211251 // Resole itemType and get rid of all pointer level if needed.
212252 itemType := slice .Type ().Elem ()
0 commit comments