github.com/zlyuancn/zstr@v0.0.0-20230412074414-14d6b645962f/values_to_map.go (about)

     1  /*
     2  -------------------------------------------------
     3     Author :       Zhang Fan
     4     date:         2020/7/17
     5     Description :
     6  -------------------------------------------------
     7  */
     8  
     9  package zstr
    10  
    11  import (
    12  	"reflect"
    13  	"strconv"
    14  )
    15  
    16  // 结构体值在渲染时读取的标签, 否则用字段名
    17  const structValueTag = `render`
    18  
    19  // 构建map, 支持 map[string]string,map[string]interface{}, KV, KVs
    20  // 其它值按顺序转为 map[string]interface{}{"*[0]": 值0, "*[1]", 值1...}
    21  func MakeMapOfValues(values ...interface{}) map[string]interface{} {
    22  	return makeMapOfValues(values)
    23  }
    24  
    25  // 构建map, 支持 map[string]string,map[string]interface{}, KV, KVs
    26  // 其它值按顺序转为 map[string]interface{}{"*[0]": 值0, "*[1]", 值1...}
    27  func makeMapOfValues(values []interface{}) map[string]interface{} {
    28  	if len(values) == 0 {
    29  		return make(map[string]interface{})
    30  	}
    31  
    32  	// 注意, nil也是一个有效的值
    33  
    34  	if len(values) == 1 {
    35  		// map, kvs
    36  		switch v := values[0].(type) {
    37  		case map[string]interface{}:
    38  			return v
    39  		case KVs:
    40  			data := make(map[string]interface{}, len(v))
    41  			for _, kv := range v {
    42  				data[kv.K] = kv.V
    43  			}
    44  			return data
    45  		}
    46  
    47  		// 其他类型
    48  		rv := reflect.Indirect(reflect.ValueOf(values[0]))
    49  		switch rv.Kind() {
    50  		case reflect.Map:
    51  			data := make(map[string]interface{}, rv.Len())
    52  			for iter := rv.MapRange(); iter.Next(); {
    53  				data[anyToString(iter.Key().Interface())] = iter.Value().Interface()
    54  			}
    55  			return data
    56  		case reflect.Struct:
    57  			aType := rv.Type()
    58  			fieldCount := aType.NumField()
    59  			data := make(map[string]interface{}, fieldCount)
    60  			for i := 0; i < fieldCount; i++ {
    61  				field := aType.Field(i)
    62  				if field.PkgPath != "" {
    63  					continue
    64  				}
    65  				key := field.Tag.Get(structValueTag)
    66  				if key == "" {
    67  					key = field.Name
    68  				}
    69  				data[key] = rv.Field(i).Interface()
    70  			}
    71  			return data
    72  		}
    73  
    74  	}
    75  
    76  	// map, kvs
    77  	switch values[0].(type) {
    78  	case KV, *KV, KVs:
    79  		data := make(map[string]interface{}, len(values))
    80  		for _, value := range values {
    81  			if kv, ok := value.(KV); ok {
    82  				data[kv.K] = kv.V
    83  				continue
    84  			}
    85  			if kv, ok := value.(*KV); ok {
    86  				data[kv.K] = kv.V
    87  				continue
    88  			}
    89  			if kvs, ok := value.(KVs); ok {
    90  				for _, kv := range kvs {
    91  					data[kv.K] = kv.V
    92  				}
    93  				continue
    94  			}
    95  
    96  			panic("所有值必须都是 zstr.KV 或者 *zstr.KV 或者 zstr.KVs")
    97  		}
    98  		return data
    99  	}
   100  
   101  	// values
   102  	data := make(map[string]interface{}, len(values))
   103  	for i, v := range values {
   104  		data[`*[`+strconv.Itoa(i)+`]`] = v
   105  	}
   106  	return data
   107  }