summaryrefslogtreecommitdiff
path: root/pkg/bindings/manifests
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2020-12-14 11:33:25 -0600
committerbaude <bbaude@redhat.com>2020-12-17 09:40:51 -0600
commit86335aa4ae01dadecd36468409d742e68b76925d (patch)
treefd6e5bfeb924db9020073685d0133b2fa38622c1 /pkg/bindings/manifests
parentc38ae47a1adf3235d8b01d724e7327e608dd8078 (diff)
downloadpodman-86335aa4ae01dadecd36468409d742e68b76925d.tar.gz
podman-86335aa4ae01dadecd36468409d742e68b76925d.tar.bz2
podman-86335aa4ae01dadecd36468409d742e68b76925d.zip
misc bindings to podman v3
manifest, system, info, volumes, play, and generate bindings are updated to always have binding options. Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'pkg/bindings/manifests')
-rw-r--r--pkg/bindings/manifests/manifests.go52
-rw-r--r--pkg/bindings/manifests/types.go36
-rw-r--r--pkg/bindings/manifests/types_add_options.go216
-rw-r--r--pkg/bindings/manifests/types_create_options.go104
-rw-r--r--pkg/bindings/manifests/types_inspect_options.go88
-rw-r--r--pkg/bindings/manifests/types_push_options.go104
-rw-r--r--pkg/bindings/manifests/types_remove_options.go88
7 files changed, 669 insertions, 19 deletions
diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go
index 0330b13e2..ef4e2a908 100644
--- a/pkg/bindings/manifests/manifests.go
+++ b/pkg/bindings/manifests/manifests.go
@@ -5,11 +5,9 @@ import (
"errors"
"net/http"
"net/url"
- "strconv"
"strings"
"github.com/containers/image/v5/manifest"
- "github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/bindings"
jsoniter "github.com/json-iterator/go"
@@ -19,8 +17,11 @@ import (
// the new manifest can also be specified. The all boolean specifies to add all entries
// of a list if the name provided is a manifest list. The ID of the new manifest list
// is returned as a string.
-func Create(ctx context.Context, names, images []string, all *bool) (string, error) {
+func Create(ctx context.Context, names, images []string, options *CreateOptions) (string, error) {
var idr handlers.IDResponse
+ if options == nil {
+ options = new(CreateOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return "", err
@@ -28,9 +29,9 @@ func Create(ctx context.Context, names, images []string, all *bool) (string, err
if len(names) < 1 {
return "", errors.New("creating a manifest requires at least one name argument")
}
- params := url.Values{}
- if all != nil {
- params.Set("all", strconv.FormatBool(*all))
+ params, err := options.ToParams()
+ if err != nil {
+ return "", err
}
for _, name := range names {
params.Add("name", name)
@@ -47,8 +48,12 @@ func Create(ctx context.Context, names, images []string, all *bool) (string, err
}
// Inspect returns a manifest list for a given name.
-func Inspect(ctx context.Context, name string) (*manifest.Schema2List, error) {
+func Inspect(ctx context.Context, name string, options *InspectOptions) (*manifest.Schema2List, error) {
var list manifest.Schema2List
+ if options == nil {
+ options = new(InspectOptions)
+ }
+ _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return nil, err
@@ -62,8 +67,11 @@ func Inspect(ctx context.Context, name string) (*manifest.Schema2List, error) {
// Add adds a manifest to a given manifest list. Additional options for the manifest
// can also be specified. The ID of the new manifest list is returned as a string
-func Add(ctx context.Context, name string, options image.ManifestAddOpts) (string, error) {
+func Add(ctx context.Context, name string, options *AddOptions) (string, error) {
var idr handlers.IDResponse
+ if options == nil {
+ options = new(AddOptions)
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return "", err
@@ -82,8 +90,12 @@ func Add(ctx context.Context, name string, options image.ManifestAddOpts) (strin
// Remove deletes a manifest entry from a manifest list. Both name and the digest to be
// removed are mandatory inputs. The ID of the new manifest list is returned as a string.
-func Remove(ctx context.Context, name, digest string) (string, error) {
+func Remove(ctx context.Context, name, digest string, options *RemoveOptions) (string, error) {
var idr handlers.IDResponse
+ if options == nil {
+ options = new(RemoveOptions)
+ }
+ _ = options
conn, err := bindings.GetClient(ctx)
if err != nil {
return "", err
@@ -100,24 +112,26 @@ func Remove(ctx context.Context, name, digest string) (string, error) {
// Push takes a manifest list and pushes to a destination. If the destination is not specified,
// the name will be used instead. If the optional all boolean is specified, all images specified
// in the list will be pushed as well.
-func Push(ctx context.Context, name string, destination *string, all *bool) (string, error) {
+func Push(ctx context.Context, name, destination string, options *PushOptions) (string, error) {
var (
idr handlers.IDResponse
)
- dest := name
+ if options == nil {
+ options = new(PushOptions)
+ }
+ if len(destination) < 1 {
+ destination = name
+ }
conn, err := bindings.GetClient(ctx)
if err != nil {
return "", err
}
- params := url.Values{}
- params.Set("image", name)
- if destination != nil {
- dest = *destination
- }
- params.Set("destination", dest)
- if all != nil {
- params.Set("all", strconv.FormatBool(*all))
+ params, err := options.ToParams()
+ if err != nil {
+ return "", err
}
+ params.Set("image", name)
+ params.Set("destination", destination)
_, err = conn.DoRequest(nil, http.MethodPost, "/manifests/%s/push", params, nil, name)
if err != nil {
return "", err
diff --git a/pkg/bindings/manifests/types.go b/pkg/bindings/manifests/types.go
new file mode 100644
index 000000000..f5054d424
--- /dev/null
+++ b/pkg/bindings/manifests/types.go
@@ -0,0 +1,36 @@
+package manifests
+
+//go:generate go run ../generator/generator.go InspectOptions
+// InspectOptions are optional options for inspecting manifests
+type InspectOptions struct {
+}
+
+//go:generate go run ../generator/generator.go CreateOptions
+// CreateOptions are optional options for creating manifests
+type CreateOptions struct {
+ All *bool
+}
+
+//go:generate go run ../generator/generator.go AddOptions
+// AddOptions are optional options for adding manifests
+type AddOptions struct {
+ All *bool
+ Annotation map[string]string
+ Arch *string
+ Features []string
+ Images []string
+ OS *string
+ OSVersion *string
+ Variant *string
+}
+
+//go:generate go run ../generator/generator.go RemoveOptions
+// RemoveOptions are optional options for removing manifests
+type RemoveOptions struct {
+}
+
+//go:generate go run ../generator/generator.go PushOptions
+// RemoveOptions are optional options for pushing manifests
+type PushOptions struct {
+ All *bool
+}
diff --git a/pkg/bindings/manifests/types_add_options.go b/pkg/bindings/manifests/types_add_options.go
new file mode 100644
index 000000000..304779f6e
--- /dev/null
+++ b/pkg/bindings/manifests/types_add_options.go
@@ -0,0 +1,216 @@
+package manifests
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-16 11:58:59.192715649 -0600 CST m=+0.000150326
+*/
+
+// Changed
+func (o *AddOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *AddOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *AddOptions) WithAll(value bool) *AddOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *AddOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
+
+// WithAnnotation
+func (o *AddOptions) WithAnnotation(value map[string]string) *AddOptions {
+ v := value
+ o.Annotation = v
+ return o
+}
+
+// GetAnnotation
+func (o *AddOptions) GetAnnotation() map[string]string {
+ var annotation map[string]string
+ if o.Annotation == nil {
+ return annotation
+ }
+ return o.Annotation
+}
+
+// WithArch
+func (o *AddOptions) WithArch(value string) *AddOptions {
+ v := &value
+ o.Arch = v
+ return o
+}
+
+// GetArch
+func (o *AddOptions) GetArch() string {
+ var arch string
+ if o.Arch == nil {
+ return arch
+ }
+ return *o.Arch
+}
+
+// WithFeatures
+func (o *AddOptions) WithFeatures(value []string) *AddOptions {
+ v := value
+ o.Features = v
+ return o
+}
+
+// GetFeatures
+func (o *AddOptions) GetFeatures() []string {
+ var features []string
+ if o.Features == nil {
+ return features
+ }
+ return o.Features
+}
+
+// WithImages
+func (o *AddOptions) WithImages(value []string) *AddOptions {
+ v := value
+ o.Images = v
+ return o
+}
+
+// GetImages
+func (o *AddOptions) GetImages() []string {
+ var images []string
+ if o.Images == nil {
+ return images
+ }
+ return o.Images
+}
+
+// WithOS
+func (o *AddOptions) WithOS(value string) *AddOptions {
+ v := &value
+ o.OS = v
+ return o
+}
+
+// GetOS
+func (o *AddOptions) GetOS() string {
+ var oS string
+ if o.OS == nil {
+ return oS
+ }
+ return *o.OS
+}
+
+// WithOSVersion
+func (o *AddOptions) WithOSVersion(value string) *AddOptions {
+ v := &value
+ o.OSVersion = v
+ return o
+}
+
+// GetOSVersion
+func (o *AddOptions) GetOSVersion() string {
+ var oSVersion string
+ if o.OSVersion == nil {
+ return oSVersion
+ }
+ return *o.OSVersion
+}
+
+// WithVariant
+func (o *AddOptions) WithVariant(value string) *AddOptions {
+ v := &value
+ o.Variant = v
+ return o
+}
+
+// GetVariant
+func (o *AddOptions) GetVariant() string {
+ var variant string
+ if o.Variant == nil {
+ return variant
+ }
+ return *o.Variant
+}
diff --git a/pkg/bindings/manifests/types_create_options.go b/pkg/bindings/manifests/types_create_options.go
new file mode 100644
index 000000000..6fccc08b6
--- /dev/null
+++ b/pkg/bindings/manifests/types_create_options.go
@@ -0,0 +1,104 @@
+package manifests
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-16 11:58:59.053719568 -0600 CST m=+0.000144061
+*/
+
+// Changed
+func (o *CreateOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *CreateOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *CreateOptions) WithAll(value bool) *CreateOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *CreateOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
diff --git a/pkg/bindings/manifests/types_inspect_options.go b/pkg/bindings/manifests/types_inspect_options.go
new file mode 100644
index 000000000..8cbcbf376
--- /dev/null
+++ b/pkg/bindings/manifests/types_inspect_options.go
@@ -0,0 +1,88 @@
+package manifests
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-16 11:58:58.908440858 -0600 CST m=+0.000142730
+*/
+
+// Changed
+func (o *InspectOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *InspectOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}
diff --git a/pkg/bindings/manifests/types_push_options.go b/pkg/bindings/manifests/types_push_options.go
new file mode 100644
index 000000000..a56b29049
--- /dev/null
+++ b/pkg/bindings/manifests/types_push_options.go
@@ -0,0 +1,104 @@
+package manifests
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-16 11:58:59.466796313 -0600 CST m=+0.000143189
+*/
+
+// Changed
+func (o *PushOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *PushOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}
+
+// WithAll
+func (o *PushOptions) WithAll(value bool) *PushOptions {
+ v := &value
+ o.All = v
+ return o
+}
+
+// GetAll
+func (o *PushOptions) GetAll() bool {
+ var all bool
+ if o.All == nil {
+ return all
+ }
+ return *o.All
+}
diff --git a/pkg/bindings/manifests/types_remove_options.go b/pkg/bindings/manifests/types_remove_options.go
new file mode 100644
index 000000000..4f8ca9e95
--- /dev/null
+++ b/pkg/bindings/manifests/types_remove_options.go
@@ -0,0 +1,88 @@
+package manifests
+
+import (
+ "net/url"
+ "reflect"
+ "strconv"
+
+ jsoniter "github.com/json-iterator/go"
+ "github.com/pkg/errors"
+)
+
+/*
+This file is generated automatically by go generate. Do not edit.
+
+Created 2020-12-16 11:58:59.33119706 -0600 CST m=+0.000143915
+*/
+
+// Changed
+func (o *RemoveOptions) Changed(fieldName string) bool {
+ r := reflect.ValueOf(o)
+ value := reflect.Indirect(r).FieldByName(fieldName)
+ return !value.IsNil()
+}
+
+// ToParams
+func (o *RemoveOptions) ToParams() (url.Values, error) {
+ params := url.Values{}
+ if o == nil {
+ return params, nil
+ }
+ json := jsoniter.ConfigCompatibleWithStandardLibrary
+ s := reflect.ValueOf(o)
+ if reflect.Ptr == s.Kind() {
+ s = s.Elem()
+ }
+ sType := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ fieldName := sType.Field(i).Name
+ if !o.Changed(fieldName) {
+ continue
+ }
+ f := s.Field(i)
+ if reflect.Ptr == f.Kind() {
+ f = f.Elem()
+ }
+ switch f.Kind() {
+ case reflect.Bool:
+ params.Set(fieldName, strconv.FormatBool(f.Bool()))
+ case reflect.String:
+ params.Set(fieldName, f.String())
+ case reflect.Int, reflect.Int64:
+ // f.Int() is always an int64
+ params.Set(fieldName, strconv.FormatInt(f.Int(), 10))
+ case reflect.Uint, reflect.Uint64:
+ // f.Uint() is always an uint64
+ params.Set(fieldName, strconv.FormatUint(f.Uint(), 10))
+ case reflect.Slice:
+ typ := reflect.TypeOf(f.Interface()).Elem()
+ slice := reflect.MakeSlice(reflect.SliceOf(typ), f.Len(), f.Cap())
+ switch typ.Kind() {
+ case reflect.String:
+ s, ok := slice.Interface().([]string)
+ if !ok {
+ return nil, errors.New("failed to convert to string slice")
+ }
+ for _, val := range s {
+ params.Add(fieldName, val)
+ }
+ default:
+ return nil, errors.Errorf("unknown slice type %s", f.Kind().String())
+ }
+ case reflect.Map:
+ lowerCaseKeys := make(map[string][]string)
+ iter := f.MapRange()
+ for iter.Next() {
+ lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string)
+
+ }
+ s, err := json.MarshalToString(lowerCaseKeys)
+ if err != nil {
+ return nil, err
+ }
+
+ params.Set(fieldName, s)
+ }
+ }
+ return params, nil
+}