func unmarshalHeader()

in oss/client.go [1117:1184]


func unmarshalHeader(result any, output *OperationOutput) error {
	val := reflect.ValueOf(result)
	switch val.Kind() {
	case reflect.Pointer, reflect.Interface:
		if val.IsNil() {
			return nil
		}
		val = val.Elem()
	}
	if val.Kind() != reflect.Struct || output == nil {
		return nil
	}

	filedInfos := map[string]fieldInfo{}

	t := val.Type()
	var usermetaKeys []string
	for k := 0; k < t.NumField(); k++ {
		if tag, ok := t.Field(k).Tag.Lookup("output"); ok {
			tokens := strings.Split(tag, ",")
			if len(tokens) < 2 {
				continue
			}
			// header|query|body,filed_name,[required,time,usermeta...]
			switch tokens[0] {
			case "header":
				lowkey := strings.ToLower(tokens[1])

				var flags int = 0
				if len(tokens) >= 3 {
					flags = parseFiledFlags(tokens[2:])
				}
				filedInfos[lowkey] = fieldInfo{idx: k, flags: flags}
				if flags&fTypeUsermeta != 0 {
					usermetaKeys = append(usermetaKeys, lowkey)
				}
			}
		}
	}
	var err error
	for key, vv := range output.Headers {
		lkey := strings.ToLower(key)
		for _, prefix := range usermetaKeys {
			if strings.HasPrefix(lkey, prefix) {
				if field, ok := filedInfos[prefix]; ok {
					if field.flags&fTypeUsermeta != 0 {
						mapKey := strings.TrimPrefix(lkey, prefix)
						err = setMapStringReflectValue(val.Field(field.idx), mapKey, vv[0])
					}
				}
			}
		}
		if field, ok := filedInfos[lkey]; ok {
			if field.flags&fTypeTime != 0 {
				if t, err := http.ParseTime(vv[0]); err == nil {
					err = setTimeReflectValue(val.Field(field.idx), t)
				}
			} else {
				err = setReflectValue(val.Field(field.idx), vv[0])
			}
			if err != nil {
				return err
			}
		}
	}

	return nil
}