package tracker import ( "errors" "net/url" "reflect" "strconv" "strings" ) func MarshalQuery(v interface{}) (string, error) { val := reflect.ValueOf(v) return marshalQuery(val) } func marshalQuery(v reflect.Value) (string, error) { if v.Kind() != reflect.Struct { return "", errors.New("must be a struct") } q := url.Values{} t := v.Type() for i := 0; i < t.NumField(); i++ { name := strings.ToLower(t.Field(i).Name) f := v.Field(i) switch f.Kind() { case reflect.Int: if x := int(f.Int()); x != 0 { q.Add(name, strconv.Itoa(int(f.Int()))) } case reflect.String: if s := f.String(); s != "" { q.Add(name, f.String()) } } } return "?" + q.Encode(), nil }