Skip to content

Commit c0419b4

Browse files
committed
Add query formatter
1 parent 245d551 commit c0419b4

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

formatters/formatters.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func init() {
1616
Register("json", formatJSON)
1717
Register("xml", formatXML)
1818
Register("yaml", formatYAML)
19+
Register("query", formatQuery)
1920
}
2021

2122
// Names returns a sorted list of valid options for the "format" parameter of Format

formatters/query.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package formatters
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
"reflect"
7+
8+
"github.com/stilvoid/please/util"
9+
)
10+
11+
// TODO: Tidy this up; it's horrid.
12+
func formatQuery(in interface{}) (string, error) {
13+
in = util.ForceStringKeys(in)
14+
15+
inMap, ok := in.(map[string]interface{})
16+
17+
if !ok {
18+
return "", fmt.Errorf("query formatter expects a map as input")
19+
}
20+
21+
var output url.Values = make(map[string][]string)
22+
23+
for key, value := range inMap {
24+
val := reflect.ValueOf(value)
25+
26+
switch val.Kind() {
27+
case reflect.Map:
28+
return "", fmt.Errorf("query formatter cannot deal with nested values")
29+
case reflect.Array, reflect.Slice:
30+
for i := 0; i < val.Len(); i++ {
31+
iVal := val.Index(i)
32+
33+
switch iVal.Kind() {
34+
case reflect.Map, reflect.Array, reflect.Slice:
35+
return "", fmt.Errorf("query formatter cannot deal with nested values")
36+
default:
37+
output.Add(key, fmt.Sprint(iVal.Interface()))
38+
}
39+
}
40+
default:
41+
output.Add(key, fmt.Sprint(value))
42+
}
43+
}
44+
45+
return output.Encode(), nil
46+
}

formatters/query_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package formatters
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func TestQuery(t *testing.T) {
9+
inputs := []interface{}{
10+
map[string]string{
11+
"foo": "bar",
12+
},
13+
map[string][]string{
14+
"foo": {"bar", "baz"},
15+
},
16+
map[string]int{
17+
"foo": 123,
18+
},
19+
map[int]int{
20+
123: 456,
21+
},
22+
map[string]string{
23+
"foo": "bar",
24+
"baz": "quux",
25+
},
26+
}
27+
28+
expecteds := []string{
29+
"foo=bar",
30+
"foo=bar&foo=baz",
31+
"foo=123",
32+
"123=456",
33+
"baz=quux&foo=bar",
34+
}
35+
36+
for i, input := range inputs {
37+
actual, err := formatQuery(input)
38+
39+
if err != nil {
40+
t.Errorf("unexpected error: %v", err)
41+
}
42+
43+
expected := expecteds[i]
44+
45+
if !reflect.DeepEqual(actual, expected) {
46+
t.Errorf("unexpected '%v', want '%v'", actual, expected)
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)