-
-
Notifications
You must be signed in to change notification settings - Fork 19
/
decode_hooks.go
88 lines (72 loc) · 1.68 KB
/
decode_hooks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//nolint:goerr113, wrapcheck
package config
import (
"errors"
"fmt"
"net/url"
"path"
"reflect"
"text/template"
"github.com/go-viper/mapstructure/v2"
)
// StringToURLHookFunc parse a string to [url.URL].
func StringToURLHookFunc() mapstructure.DecodeHookFuncType {
return func(
f reflect.Type,
t reflect.Type,
data interface{},
) (interface{}, error) {
if f.Kind() != reflect.String {
return data, nil
}
if t != reflect.TypeOf(url.URL{}) {
return data, nil
}
dataString, ok := data.(string)
if !ok {
return nil, errors.New("unable to cast to string")
}
// Convert it by parsing
uri, err := url.Parse(dataString)
if err != nil {
return nil, err
}
if uri.String() == "" {
return uri, nil
}
if uri.Scheme == "" {
return nil, fmt.Errorf("invalid URL %s: empty scheme", dataString)
}
if uri.Host == "" && uri.Path == "" {
return nil, fmt.Errorf("invalid URL %s: empty hostname", dataString)
}
return uri, nil
}
}
// StringToTemplateHookFunc parse a string to [template.Template].
func StringToTemplateHookFunc() mapstructure.DecodeHookFuncType {
return func(
f reflect.Type,
t reflect.Type,
data interface{},
) (interface{}, error) {
if f.Kind() != reflect.String {
return data, nil
}
if t != reflect.TypeOf(template.Template{}) {
return data, nil
}
dataString, ok := data.(string)
if !ok {
return nil, errors.New("unable to cast to string")
}
if dataString == "" {
return template.Template{}, nil
}
tmpl, err := template.New(path.Base(dataString)).ParseFiles(dataString)
if err != nil {
return template.Template{}, fmt.Errorf("error paring template files: %w", err)
}
return tmpl, err
}
}