// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. package utils import ( "context" "encoding/json" "fmt" "net/http" "net/url" "reflect" ) func PopulateQueryParams(ctx context.Context, req *http.Request, queryParams interface{}, globals map[string]map[string]map[string]interface{}) error { queryParamsStructType := reflect.TypeOf(queryParams) queryParamsValType := reflect.ValueOf(queryParams) values := url.Values{} for i := 0; i < queryParamsStructType.NumField(); i++ { fieldType := queryParamsStructType.Field(i) valType := queryParamsValType.Field(i) requestTag := getRequestTag(fieldType) if requestTag != nil { continue } qpTag := parseQueryParamTag(fieldType) if qpTag == nil { continue } valType = populateFromGlobals(fieldType, valType, "queryParam", globals) if qpTag.Serialization != "" { vals, err := populateSerializedParams(qpTag, fieldType.Type, valType) if err != nil { return err } for k, v := range vals { values.Add(k, v) } } else { switch qpTag.Style { case "deepObject": vals := populateDeepObjectParams(req, qpTag, fieldType.Type, valType) for k, v := range vals { for _, vv := range v { values.Add(k, vv) } } case "form": vals := populateFormParams(req, qpTag, fieldType.Type, valType, ",") for k, v := range vals { for _, vv := range v { values.Add(k, vv) } } case "pipeDelimited": vals := populateFormParams(req, qpTag, fieldType.Type, valType, "|") for k, v := range vals { for _, vv := range v { values.Add(k, vv) } } default: return fmt.Errorf("unsupported style: %s", qpTag.Style) } } } req.URL.RawQuery = values.Encode() return nil } func populateSerializedParams(tag *paramTag, objType reflect.Type, objValue reflect.Value) (map[string]string, error) { if isNil(objType, objValue) { return nil, nil } if objType.Kind() == reflect.Pointer { objValue = objValue.Elem() } values := map[string]string{} switch tag.Serialization { case "json": data, err := json.Marshal(objValue.Interface()) if err != nil { return nil, fmt.Errorf("error marshaling json: %v", err) } values[tag.ParamName] = string(data) } return values, nil } func populateDeepObjectParams(req *http.Request, tag *paramTag, objType reflect.Type, objValue reflect.Value) url.Values { values := url.Values{} if isNil(objType, objValue) { return values } if objType.Kind() == reflect.Pointer { objType = objType.Elem() objValue = objValue.Elem() } switch objType.Kind() { case reflect.Struct: for i := 0; i < objType.NumField(); i++ { fieldType := objType.Field(i) valType := objValue.Field(i) if isNil(fieldType.Type, valType) { continue } if fieldType.Type.Kind() == reflect.Pointer { valType = valType.Elem() } qpTag := parseQueryParamTag(fieldType) if qpTag == nil { continue } switch valType.Kind() { case reflect.Array, reflect.Slice: for i := 0; i < valType.Len(); i++ { values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Index(i).Interface())) } default: values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, qpTag.ParamName), valToString(valType.Interface())) } } case reflect.Map: iter := objValue.MapRange() for iter.Next() { switch iter.Value().Kind() { case reflect.Array, reflect.Slice: for i := 0; i < iter.Value().Len(); i++ { values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Index(i).Interface())) } default: values.Add(fmt.Sprintf("%s[%s]", tag.ParamName, iter.Key().String()), valToString(iter.Value().Interface())) } } } return values } func populateFormParams(req *http.Request, tag *paramTag, objType reflect.Type, objValue reflect.Value, delimiter string) url.Values { return populateForm(tag.ParamName, tag.Explode, objType, objValue, delimiter, func(fieldType reflect.StructField) string { qpTag := parseQueryParamTag(fieldType) if qpTag == nil { return "" } return qpTag.ParamName }) } type paramTag struct { Style string Explode bool ParamName string Serialization string } func parseQueryParamTag(field reflect.StructField) *paramTag { return parseParamTag(queryParamTagKey, field, "form", true) }