github.com/containers/podman/v4@v4.9.4/pkg/bindings/internal/util/util.go (about) 1 package util 2 3 import ( 4 "errors" 5 "fmt" 6 "net/url" 7 "reflect" 8 "strconv" 9 "strings" 10 11 jsoniter "github.com/json-iterator/go" 12 ) 13 14 func IsSimpleType(f reflect.Value) bool { 15 if _, ok := f.Interface().(fmt.Stringer); ok { 16 return true 17 } 18 19 switch f.Kind() { 20 case reflect.Bool, reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64, reflect.String: 21 return true 22 } 23 24 return false 25 } 26 27 func SimpleTypeToParam(f reflect.Value) string { 28 if s, ok := f.Interface().(fmt.Stringer); ok { 29 return s.String() 30 } 31 32 switch f.Kind() { 33 case reflect.Bool: 34 return strconv.FormatBool(f.Bool()) 35 case reflect.Int, reflect.Int64: 36 // f.Int() is always an int64 37 return strconv.FormatInt(f.Int(), 10) 38 case reflect.Uint, reflect.Uint64: 39 // f.Uint() is always an uint64 40 return strconv.FormatUint(f.Uint(), 10) 41 case reflect.String: 42 return f.String() 43 } 44 45 panic("the input parameter is not a simple type") 46 } 47 48 func Changed(o interface{}, fieldName string) bool { 49 r := reflect.ValueOf(o) 50 value := reflect.Indirect(r).FieldByName(fieldName) 51 return !value.IsNil() 52 } 53 54 func ToParams(o interface{}) (url.Values, error) { 55 params := url.Values{} 56 if o == nil || reflect.ValueOf(o).IsNil() { 57 return params, nil 58 } 59 json := jsoniter.ConfigCompatibleWithStandardLibrary 60 s := reflect.ValueOf(o) 61 if reflect.Ptr == s.Kind() { 62 s = s.Elem() 63 } 64 sType := s.Type() 65 for i := 0; i < s.NumField(); i++ { 66 fieldName := sType.Field(i).Name 67 if !Changed(o, fieldName) { 68 continue 69 } 70 fieldName = strings.ToLower(fieldName) 71 f := s.Field(i) 72 if reflect.Ptr == f.Kind() { 73 f = f.Elem() 74 } 75 paramName := fieldName 76 if pn, ok := sType.Field(i).Tag.Lookup("schema"); ok { 77 if pn == "-" { 78 continue 79 } 80 paramName = pn 81 } 82 switch { 83 case IsSimpleType(f): 84 params.Set(paramName, SimpleTypeToParam(f)) 85 case f.Kind() == reflect.Slice: 86 for i := 0; i < f.Len(); i++ { 87 elem := f.Index(i) 88 if IsSimpleType(elem) { 89 params.Add(paramName, SimpleTypeToParam(elem)) 90 } else { 91 return nil, errors.New("slices must contain only simple types") 92 } 93 } 94 case f.Kind() == reflect.Map: 95 lowerCaseKeys := make(map[string]interface{}) 96 iter := f.MapRange() 97 for iter.Next() { 98 lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface() 99 } 100 s, err := json.MarshalToString(lowerCaseKeys) 101 if err != nil { 102 return nil, err 103 } 104 105 params.Set(paramName, s) 106 } 107 } 108 return params, nil 109 } 110 111 func MapToArrayString(data map[string]string) []string { 112 l := make([]string, 0) 113 for k, v := range data { 114 l = append(l, k+"="+v) 115 } 116 return l 117 }