...
1
2
3
4
5
6
7
8
9
10
11 package viper
12
13 import (
14 "fmt"
15 "os"
16 "path/filepath"
17 "runtime"
18 "strings"
19 "unicode"
20
21 slog "github.com/sagikazarmark/slog-shim"
22 "github.com/spf13/cast"
23 )
24
25
26 type ConfigParseError struct {
27 err error
28 }
29
30
31 func (pe ConfigParseError) Error() string {
32 return fmt.Sprintf("While parsing config: %s", pe.err.Error())
33 }
34
35
36 func (pe ConfigParseError) Unwrap() error {
37 return pe.err
38 }
39
40
41
42 func toCaseInsensitiveValue(value any) any {
43 switch v := value.(type) {
44 case map[any]any:
45 value = copyAndInsensitiviseMap(cast.ToStringMap(v))
46 case map[string]any:
47 value = copyAndInsensitiviseMap(v)
48 }
49
50 return value
51 }
52
53
54
55 func copyAndInsensitiviseMap(m map[string]any) map[string]any {
56 nm := make(map[string]any)
57
58 for key, val := range m {
59 lkey := strings.ToLower(key)
60 switch v := val.(type) {
61 case map[any]any:
62 nm[lkey] = copyAndInsensitiviseMap(cast.ToStringMap(v))
63 case map[string]any:
64 nm[lkey] = copyAndInsensitiviseMap(v)
65 default:
66 nm[lkey] = v
67 }
68 }
69
70 return nm
71 }
72
73 func insensitiviseVal(val any) any {
74 switch v := val.(type) {
75 case map[any]any:
76
77 val = cast.ToStringMap(val)
78 insensitiviseMap(val.(map[string]any))
79 case map[string]any:
80
81 insensitiviseMap(v)
82 case []any:
83
84 insensitiveArray(v)
85 }
86 return val
87 }
88
89 func insensitiviseMap(m map[string]any) {
90 for key, val := range m {
91 val = insensitiviseVal(val)
92 lower := strings.ToLower(key)
93 if key != lower {
94
95 delete(m, key)
96 }
97
98 m[lower] = val
99 }
100 }
101
102 func insensitiveArray(a []any) {
103 for i, val := range a {
104 a[i] = insensitiviseVal(val)
105 }
106 }
107
108 func absPathify(logger *slog.Logger, inPath string) string {
109 logger.Info("trying to resolve absolute path", "path", inPath)
110
111 if inPath == "$HOME" || strings.HasPrefix(inPath, "$HOME"+string(os.PathSeparator)) {
112 inPath = userHomeDir() + inPath[5:]
113 }
114
115 inPath = os.ExpandEnv(inPath)
116
117 if filepath.IsAbs(inPath) {
118 return filepath.Clean(inPath)
119 }
120
121 p, err := filepath.Abs(inPath)
122 if err == nil {
123 return filepath.Clean(p)
124 }
125
126 logger.Error(fmt.Errorf("could not discover absolute path: %w", err).Error())
127
128 return ""
129 }
130
131 func stringInSlice(a string, list []string) bool {
132 for _, b := range list {
133 if b == a {
134 return true
135 }
136 }
137 return false
138 }
139
140 func userHomeDir() string {
141 if runtime.GOOS == "windows" {
142 home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
143 if home == "" {
144 home = os.Getenv("USERPROFILE")
145 }
146 return home
147 }
148 return os.Getenv("HOME")
149 }
150
151 func safeMul(a, b uint) uint {
152 c := a * b
153 if a > 1 && b > 1 && c/b != a {
154 return 0
155 }
156 return c
157 }
158
159
160 func parseSizeInBytes(sizeStr string) uint {
161 sizeStr = strings.TrimSpace(sizeStr)
162 lastChar := len(sizeStr) - 1
163 multiplier := uint(1)
164
165 if lastChar > 0 {
166 if sizeStr[lastChar] == 'b' || sizeStr[lastChar] == 'B' {
167 if lastChar > 1 {
168 switch unicode.ToLower(rune(sizeStr[lastChar-1])) {
169 case 'k':
170 multiplier = 1 << 10
171 sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
172 case 'm':
173 multiplier = 1 << 20
174 sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
175 case 'g':
176 multiplier = 1 << 30
177 sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
178 default:
179 multiplier = 1
180 sizeStr = strings.TrimSpace(sizeStr[:lastChar])
181 }
182 }
183 }
184 }
185
186 size := cast.ToInt(sizeStr)
187 if size < 0 {
188 size = 0
189 }
190
191 return safeMul(uint(size), multiplier)
192 }
193
194
195
196
197
198
199
200
201 func deepSearch(m map[string]any, path []string) map[string]any {
202 for _, k := range path {
203 m2, ok := m[k]
204 if !ok {
205
206
207 m3 := make(map[string]any)
208 m[k] = m3
209 m = m3
210 continue
211 }
212 m3, ok := m2.(map[string]any)
213 if !ok {
214
215
216 m3 = make(map[string]any)
217 m[k] = m3
218 }
219
220 m = m3
221 }
222 return m
223 }
224
View as plain text