github.com/zhongdalu/gf@v1.0.0/g/internal/structs/structs_map.go (about)

     1  // Copyright 2019 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/zhongdalu/gf.
     6  
     7  package structs
     8  
     9  import (
    10  	"reflect"
    11  
    12  	"github.com/zhongdalu/gf/third/github.com/fatih/structs"
    13  )
    14  
    15  // MapField retrieves struct field as map[name/tag]*Field from <pointer>, and returns it.
    16  //
    17  // The parameter <recursive> specifies whether retrieving the struct field recursively.
    18  //
    19  // Note that it only retrieves the exported attributes with first letter up-case from struct.
    20  func MapField(pointer interface{}, priority []string, recursive bool) map[string]*Field {
    21  	fieldMap := make(map[string]*Field)
    22  	fields := ([]*structs.Field)(nil)
    23  	if v, ok := pointer.(reflect.Value); ok {
    24  		fields = structs.Fields(v.Interface())
    25  	} else {
    26  		fields = structs.Fields(pointer)
    27  	}
    28  	tag := ""
    29  	name := ""
    30  	for _, field := range fields {
    31  		name = field.Name()
    32  		// Only retrieve exported attributes.
    33  		if name[0] < byte('A') || name[0] > byte('Z') {
    34  			continue
    35  		}
    36  		fieldMap[name] = field
    37  		tag = ""
    38  		for _, p := range priority {
    39  			tag = field.Tag(p)
    40  			if tag != "" {
    41  				break
    42  			}
    43  		}
    44  		if tag != "" {
    45  			fieldMap[tag] = field
    46  		}
    47  		if recursive {
    48  			rv := reflect.ValueOf(field.Value())
    49  			kind := rv.Kind()
    50  			if kind == reflect.Ptr {
    51  				rv = rv.Elem()
    52  				kind = rv.Kind()
    53  			}
    54  			if kind == reflect.Struct {
    55  				for k, v := range MapField(rv, priority, true) {
    56  					if _, ok := fieldMap[k]; !ok {
    57  						fieldMap[k] = v
    58  					}
    59  				}
    60  			}
    61  		}
    62  	}
    63  	return fieldMap
    64  }