1package sprig
2
3import (
4	"fmt"
5	"net/url"
6	"reflect"
7)
8
9func dictGetOrEmpty(dict map[string]interface{}, key string) string {
10	value, ok := dict[key]
11	if !ok {
12		return ""
13	}
14	tp := reflect.TypeOf(value).Kind()
15	if tp != reflect.String {
16		panic(fmt.Sprintf("unable to parse %s key, must be of type string, but %s found", key, tp.String()))
17	}
18	return reflect.ValueOf(value).String()
19}
20
21// parses given URL to return dict object
22func urlParse(v string) map[string]interface{} {
23	dict := map[string]interface{}{}
24	parsedURL, err := url.Parse(v)
25	if err != nil {
26		panic(fmt.Sprintf("unable to parse url: %s", err))
27	}
28	dict["scheme"] = parsedURL.Scheme
29	dict["host"] = parsedURL.Host
30	dict["hostname"] = parsedURL.Hostname()
31	dict["path"] = parsedURL.Path
32	dict["query"] = parsedURL.RawQuery
33	dict["opaque"] = parsedURL.Opaque
34	dict["fragment"] = parsedURL.Fragment
35	if parsedURL.User != nil {
36		dict["userinfo"] = parsedURL.User.String()
37	} else {
38		dict["userinfo"] = ""
39	}
40
41	return dict
42}
43
44// join given dict to URL string
45func urlJoin(d map[string]interface{}) string {
46	resURL := url.URL{
47		Scheme:   dictGetOrEmpty(d, "scheme"),
48		Host:     dictGetOrEmpty(d, "host"),
49		Path:     dictGetOrEmpty(d, "path"),
50		RawQuery: dictGetOrEmpty(d, "query"),
51		Opaque:   dictGetOrEmpty(d, "opaque"),
52		Fragment: dictGetOrEmpty(d, "fragment"),
53	}
54	userinfo := dictGetOrEmpty(d, "userinfo")
55	var user *url.Userinfo
56	if userinfo != "" {
57		tempURL, err := url.Parse(fmt.Sprintf("proto://%s@host", userinfo))
58		if err != nil {
59			panic(fmt.Sprintf("unable to parse userinfo in dict: %s", err))
60		}
61		user = tempURL.User
62	}
63
64	resURL.User = user
65	return resURL.String()
66}
67