// Package helpers provides parameter filtering utilities. package helpers import ( "fmt" "reflect" "strings" "github.com/aws/aws-sdk-go/internal/model/api" "github.com/aws/aws-sdk-go/internal/util" "github.com/aws/aws-sdk-go/internal/util/utilsort" ) // A paramFiller provides string formatting for a shape and its types. type paramFiller struct { prefixPackageName bool } // typeName returns the type name of a shape. func (f paramFiller) typeName(shape *api.Shape) string { if f.prefixPackageName && shape.Type == "structure" { return "*" + shape.API.PackageName() + "." + shape.GoTypeElem() } return shape.GoType() } // ParamsStructFromJSON returns a JSON string representation of a structure. func ParamsStructFromJSON(value interface{}, shape *api.Shape, prefixPackageName bool) string { f := paramFiller{prefixPackageName: prefixPackageName} return util.GoFmt(f.paramsStructAny(value, shape)) } // paramsStructAny returns the string representation of any value. func (f paramFiller) paramsStructAny(value interface{}, shape *api.Shape) string { if value == nil { return "" } switch shape.Type { case "structure": if value != nil { vmap := value.(map[string]interface{}) return f.paramsStructStruct(vmap, shape) } case "list": vlist := value.([]interface{}) return f.paramsStructList(vlist, shape) case "map": vmap := value.(map[string]interface{}) return f.paramsStructMap(vmap, shape) case "string", "character": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() { return fmt.Sprintf("aws.String(%#v)", v.Interface()) } case "blob": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() && shape.Streaming { return fmt.Sprintf("aws.ReadSeekCloser(bytes.NewBufferString(%#v))", v.Interface()) } else if v.IsValid() { return fmt.Sprintf("[]byte(%#v)", v.Interface()) } case "boolean": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() { return fmt.Sprintf("aws.Bool(%#v)", v.Interface()) } case "integer", "long": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() { return fmt.Sprintf("aws.Int64(%v)", v.Interface()) } case "float", "double": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() { return fmt.Sprintf("aws.Float64(%v)", v.Interface()) } case "timestamp": v := reflect.Indirect(reflect.ValueOf(value)) if v.IsValid() { return fmt.Sprintf("aws.Time(time.Unix(%d, 0))", int(v.Float())) } default: panic("Unhandled type " + shape.Type) } return "" } // paramsStructStruct returns the string representation of a structure func (f paramFiller) paramsStructStruct(value map[string]interface{}, shape *api.Shape) string { out := "&" + f.typeName(shape)[1:] + "{\n" for _, n := range shape.MemberNames() { ref := shape.MemberRefs[n] name := findMember(value, n) if val := f.paramsStructAny(value[name], ref.Shape); val != "" { out += fmt.Sprintf("%s: %s,\n", n, val) } } out += "}" return out } // paramsStructMap returns the string representation of a map of values func (f paramFiller) paramsStructMap(value map[string]interface{}, shape *api.Shape) string { out := f.typeName(shape) + "{\n" keys := utilsort.SortedKeys(value) for _, k := range keys { v := value[k] out += fmt.Sprintf("%q: %s,\n", k, f.paramsStructAny(v, shape.ValueRef.Shape)) } out += "}" return out } // paramsStructList returns the string representation of slice of values func (f paramFiller) paramsStructList(value []interface{}, shape *api.Shape) string { out := f.typeName(shape) + "{\n" for _, v := range value { out += fmt.Sprintf("%s,\n", f.paramsStructAny(v, shape.MemberRef.Shape)) } out += "}" return out } // findMember searches a map for a key ignoring case. Returns the map key if found. func findMember(value map[string]interface{}, key string) string { for actualKey := range value { if strings.ToLower(key) == strings.ToLower(actualKey) { return actualKey } } return "" }