Skip to content

Commit 1dc2ac8

Browse files
committed
move solution to correct file
1 parent 4db62fc commit 1dc2ac8

File tree

2 files changed

+66
-66
lines changed

2 files changed

+66
-66
lines changed

internal/tools/config.go

+66
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212

1313
"github.com/FZambia/viper-lite"
1414
"github.com/google/uuid"
15+
"github.com/mitchellh/mapstructure"
16+
"github.com/rs/zerolog/log"
1517
)
1618

1719
// pathExists returns whether the given file or directory exists or not
@@ -168,3 +170,67 @@ func OptionalStringChoice(v *viper.Viper, key string, choices []string) (string,
168170
}
169171
return val, nil
170172
}
173+
174+
// DecoderConfig returns default mapstructure.DecoderConfig with support
175+
// of time.Duration values & string slices & Duration
176+
func DecoderConfig(output any) *mapstructure.DecoderConfig {
177+
return &mapstructure.DecoderConfig{
178+
Metadata: nil,
179+
Result: output,
180+
WeaklyTypedInput: true,
181+
DecodeHook: mapstructure.ComposeDecodeHookFunc(
182+
StringToDurationHookFunc(),
183+
mapstructure.StringToTimeDurationHookFunc(),
184+
mapstructure.StringToSliceHookFunc(","),
185+
),
186+
}
187+
}
188+
189+
func DecodeSlice(v *viper.Viper, dst any, key string) []byte {
190+
var jsonData []byte
191+
var err error
192+
switch val := v.Get(key).(type) {
193+
case string:
194+
jsonData = []byte(val)
195+
err = json.Unmarshal([]byte(val), dst)
196+
case []any:
197+
jsonData, err = json.Marshal(translateMap(val))
198+
if err != nil {
199+
log.Fatal().Err(err).Msgf("error marshalling config %s slice", key)
200+
}
201+
decoderCfg := DecoderConfig(dst)
202+
decoder, newErr := mapstructure.NewDecoder(decoderCfg)
203+
if newErr != nil {
204+
log.Fatal().Msg(newErr.Error())
205+
}
206+
err = decoder.Decode(v.Get(key))
207+
default:
208+
err = fmt.Errorf("unknown %s type: %T", key, val)
209+
}
210+
if err != nil {
211+
log.Fatal().Err(err).Msgf("malformed %s", key)
212+
}
213+
return jsonData
214+
}
215+
216+
// translateMap is a helper to deal with map[any]any which YAML uses when unmarshalling.
217+
// We always use string keys and not making this transform results into errors on JSON marshaling.
218+
func translateMap(input []any) []map[string]any {
219+
var result []map[string]any
220+
for _, elem := range input {
221+
switch v := elem.(type) {
222+
case map[any]any:
223+
translatedMap := make(map[string]any)
224+
for key, value := range v {
225+
stringKey := fmt.Sprintf("%v", key)
226+
translatedMap[stringKey] = value
227+
}
228+
result = append(result, translatedMap)
229+
case map[string]any:
230+
result = append(result, v)
231+
default:
232+
log.Fatal().Msgf("invalid type in slice: %T", elem)
233+
}
234+
}
235+
return result
236+
}

internal/tools/duration.go

-66
Original file line numberDiff line numberDiff line change
@@ -7,75 +7,9 @@ import (
77
"reflect"
88
"time"
99

10-
"github.com/FZambia/viper-lite"
1110
"github.com/mitchellh/mapstructure"
12-
"github.com/rs/zerolog/log"
1311
)
1412

15-
func DecodeSlice(v *viper.Viper, dst any, key string) []byte {
16-
var jsonData []byte
17-
var err error
18-
switch val := v.Get(key).(type) {
19-
case string:
20-
jsonData = []byte(val)
21-
err = json.Unmarshal([]byte(val), dst)
22-
case []any:
23-
jsonData, err = json.Marshal(translateMap(val))
24-
if err != nil {
25-
log.Fatal().Err(err).Msgf("error marshalling config %s slice", key)
26-
}
27-
decoderCfg := DecoderConfig(dst)
28-
decoder, newErr := mapstructure.NewDecoder(decoderCfg)
29-
if newErr != nil {
30-
log.Fatal().Msg(newErr.Error())
31-
}
32-
err = decoder.Decode(v.Get(key))
33-
default:
34-
err = fmt.Errorf("unknown %s type: %T", key, val)
35-
}
36-
if err != nil {
37-
log.Fatal().Err(err).Msgf("malformed %s", key)
38-
}
39-
return jsonData
40-
}
41-
42-
// translateMap is a helper to deal with map[any]any which YAML uses when unmarshalling.
43-
// We always use string keys and not making this transform results into errors on JSON marshaling.
44-
func translateMap(input []any) []map[string]any {
45-
var result []map[string]any
46-
for _, elem := range input {
47-
switch v := elem.(type) {
48-
case map[any]any:
49-
translatedMap := make(map[string]any)
50-
for key, value := range v {
51-
stringKey := fmt.Sprintf("%v", key)
52-
translatedMap[stringKey] = value
53-
}
54-
result = append(result, translatedMap)
55-
case map[string]any:
56-
result = append(result, v)
57-
default:
58-
log.Fatal().Msgf("invalid type in slice: %T", elem)
59-
}
60-
}
61-
return result
62-
}
63-
64-
// DecoderConfig returns default mapstructure.DecoderConfig with support
65-
// of time.Duration values & string slices & Duration
66-
func DecoderConfig(output any) *mapstructure.DecoderConfig {
67-
return &mapstructure.DecoderConfig{
68-
Metadata: nil,
69-
Result: output,
70-
WeaklyTypedInput: true,
71-
DecodeHook: mapstructure.ComposeDecodeHookFunc(
72-
StringToDurationHookFunc(),
73-
mapstructure.StringToTimeDurationHookFunc(),
74-
mapstructure.StringToSliceHookFunc(","),
75-
),
76-
}
77-
}
78-
7913
type Duration time.Duration
8014

8115
// StringToDurationHookFunc returns a DecodeHookFunc that converts

0 commit comments

Comments
 (0)