Skip to content

Instantly share code, notes, and snippets.

@rawnly
Last active April 7, 2022 19:50
Show Gist options
  • Save rawnly/77792d8dba98748069f3098e547d8de5 to your computer and use it in GitHub Desktop.
Save rawnly/77792d8dba98748069f3098e547d8de5 to your computer and use it in GitHub Desktop.

Example Usage

Warn! Text encoding for urls has not been implemented.

package main

import "fmt"

type Parrams struct {
  Query string `url:"q"`
  Count int `url:"count"`
  Scope []string `url:"scope" separator:"comma"`
}

func main() {

  params := Params {
    Query: "project",
    Count: 1,
    Scope: []string{ "projects", "files" },
  }
  
  qs := QueryString(params)
  
  fmt.Println(qs) // => ?q=project&count=1&scope=projects,files
}
package api
import (
"fmt"
"reflect"
"strconv"
"strings"
)
func QueryString[T any](p T) string {
t := reflect.TypeOf(p)
v := reflect.ValueOf(p)
result := ""
for i := 0; i < t.NumField(); i++ {
value := v.Field(i)
field := t.Field(i)
tag := field.Tag
if len(tag) == 0 {
continue
}
if len(result) == 0 {
result = "?"
}
var joinChar rune
var val string
if result != "?" {
joinChar = '&'
}
switch field.Type.Kind() {
case reflect.Slice:
var separator string
// TODO: convert separator to encoded string such as `%20` for space
switch tag.Get("separator") {
case "space":
separator = " "
default:
separator = ","
}
val = strings.Join(value.Interface().([]string), separator)
case reflect.Int:
val = strconv.FormatInt(value.Int(), 10)
default:
// TODO: convert string to encoded uri
val = value.String()
}
if len(val) > 0 {
result += fmt.Sprintf("%s%s=%s", string(joinChar), tag.Get("url"), val)
}
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment