From 7727cf2f9d64027e05cbd25466a0af6e25f628e0 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 14 Jul 2016 19:04:20 +0200 Subject: Split query --- query/query.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 query/query.go (limited to 'query/query.go') diff --git a/query/query.go b/query/query.go new file mode 100644 index 0000000..83214b8 --- /dev/null +++ b/query/query.go @@ -0,0 +1,61 @@ +package query + +import ( + "errors" + "net/url" + "reflect" + "strconv" + "strings" +) + +func Marshal(v interface{}) (string, error) { + val := reflect.ValueOf(v) + return marshalQuery(val) +} + +func parseTag(tag string) (string, string) { + if i := strings.Index(tag, ","); i != -1 { + return tag[:i], tag[i+1:] + } + return tag, "" +} + +func isZero(v reflect.Value) bool { + switch v.Kind() { + case reflect.String: + return v.String() == "" + case reflect.Int: + return v.Int() == 0 + } + return false +} + +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) + tag, param := parseTag(t.Field(i).Tag.Get("query")) + if tag != "" { + name = tag + } + f := v.Field(i) + if param == "optional" && isZero(f) { + continue + } + switch f.Kind() { + case reflect.Int: + q.Add(name, strconv.Itoa(int(f.Int()))) + case reflect.String: + q.Add(name, f.String()) + case reflect.Slice: + if f.Type().Elem().Kind() == reflect.Uint8 { + q.Add(name, string(f.Bytes())) + } + } + } + return "?" + q.Encode(), nil +} -- cgit v1.2.3