parseParamLocation inspects the tags on f to determine which request parameter location it represents (path, query, header, form, or cookie). It populates a paramFieldInfo with the location, name, and any location-specific settings such as explode and style for query params, or type coercion for coo
(f reflect.StructField, registry Registry)
| 130 | // Panics if the field type is a pointer, which is not currently supported for |
| 131 | // any parameter location. |
| 132 | func parseParamLocation(f reflect.StructField, registry Registry) (*paramLocation, bool) { |
| 133 | pfi := ¶mFieldInfo{Type: f.Type} |
| 134 | |
| 135 | if reflect.PointerTo(f.Type).Implements(paramWrapperType) { |
| 136 | pfi.Type = reflect.New(f.Type).Interface().(ParamWrapper).Receiver().Type() |
| 137 | } |
| 138 | |
| 139 | if def := f.Tag.Get("default"); def != "" { |
| 140 | pfi.Default = def |
| 141 | } |
| 142 | |
| 143 | result := ¶mLocation{pfi: pfi} |
| 144 | |
| 145 | switch { |
| 146 | case f.Tag.Get("path") != "": |
| 147 | pfi.Loc = "path" |
| 148 | pfi.Name = f.Tag.Get("path") |
| 149 | pfi.Required = true |
| 150 | case f.Tag.Get("query") != "": |
| 151 | raw := f.Tag.Get("query") |
| 152 | split := strings.Split(raw, ",") |
| 153 | pfi.Loc = "query" |
| 154 | pfi.Name = split[0] |
| 155 | // If `in` is `query` then `explode` defaults to true. Parsing is *much* |
| 156 | // easier if we use comma-separated values, so we disable explode by default. |
| 157 | if slices.Contains(split[1:], "explode") { |
| 158 | pfi.Explode = true |
| 159 | } |
| 160 | if slices.Contains(split[1:], styleDeepObject) { |
| 161 | pfi.Style = styleDeepObject |
| 162 | } |
| 163 | result.explode = &pfi.Explode |
| 164 | case f.Tag.Get("header") != "": |
| 165 | pfi.Loc = "header" |
| 166 | pfi.Name = f.Tag.Get("header") |
| 167 | case f.Tag.Get("form") != "": |
| 168 | pfi.Loc = "form" |
| 169 | pfi.Name = f.Tag.Get("form") |
| 170 | pfi.Required = !getConfig[registryConfig](registry).FieldsOptionalByDefault |
| 171 | case f.Tag.Get("cookie") != "": |
| 172 | pfi.Loc = "cookie" |
| 173 | pfi.Name = f.Tag.Get("cookie") |
| 174 | if f.Type == cookieType { |
| 175 | // Special case: parsed from a string input to an `http.Cookie` struct. |
| 176 | pfi.Type = stringType |
| 177 | } |
| 178 | default: |
| 179 | return nil, false |
| 180 | } |
| 181 | |
| 182 | // Pointer check comes after tag detection — untagged pointer fields are fine. |
| 183 | if f.Type.Kind() == reflect.Pointer { |
| 184 | // TODO: support pointers? The problem is that when we dynamically |
| 185 | // create an instance of the input struct the `params.Every(...)` |
| 186 | // call cannot set them as the value is `reflect.Invalid` unless |
| 187 | // dynamically allocated, but we don't know when to allocate until |
| 188 | // after the `Every` callback has run. Doable, but a bigger change. |
| 189 | panic("pointers are not supported for form/header/path/query parameters") |
no test coverage detected
searching dependent graphs…