ExtractQueryParameters moves the query parameters of the URL into the options using reflection. The options must be a pointer to a struct which contains only string or bool fields (more types will be supported in the future), and tagged for JSON serialization. All of the URL's query parameters wil
(u *url.URL, options any)
| 144 | // |
| 145 | // All of the URL's query parameters will be removed after calling this method. |
| 146 | func ExtractQueryParameters(u *url.URL, options any) { |
| 147 | type field struct { |
| 148 | index int |
| 149 | kind reflect.Kind |
| 150 | } |
| 151 | |
| 152 | // First, find all JSON fields in the options struct type. |
| 153 | o := reflect.Indirect(reflect.ValueOf(options)) |
| 154 | ty := o.Type() |
| 155 | numFields := ty.NumField() |
| 156 | tagToField := make(map[string]field, numFields) |
| 157 | for i := 0; i < numFields; i++ { |
| 158 | f := ty.Field(i) |
| 159 | tag := f.Tag.Get("json") |
| 160 | tagToField[tag] = field{index: i, kind: f.Type.Kind()} |
| 161 | } |
| 162 | |
| 163 | // Then, read content from the URL into the options. |
| 164 | for key, params := range u.Query() { |
| 165 | if len(params) == 0 { |
| 166 | continue |
| 167 | } |
| 168 | param := params[0] |
| 169 | normalizedKey := strings.ToLower(strings.ReplaceAll(key, "_", "-")) |
| 170 | if f, ok := tagToField[normalizedKey]; ok { |
| 171 | field := o.Field(f.index) |
| 172 | switch f.kind { |
| 173 | case reflect.Bool: |
| 174 | if v, e := strconv.ParseBool(param); e == nil { |
| 175 | field.SetBool(v) |
| 176 | } |
| 177 | case reflect.String: |
| 178 | field.SetString(param) |
| 179 | default: |
| 180 | panic("BackendOption introduced an unsupported kind, please handle it! " + f.kind.String()) |
| 181 | } |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | // Clean up the URL finally. |
| 186 | u.RawQuery = "" |
| 187 | } |
| 188 | |
| 189 | // FormatBackendURL obtains the raw URL which can be used the reconstruct the |
| 190 | // backend. The returned URL does not contain options for further configurating |