Skip to content

Commit e2d757e

Browse files
committed
add new func ResolveSlice
1 parent a541dcd commit e2d757e

File tree

5 files changed

+219
-8
lines changed

5 files changed

+219
-8
lines changed

coverage.out

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
mode: set
2+
github.com/containeroo/resolver/env.go:17.61,19.12 2 1
3+
github.com/containeroo/resolver/env.go:19.12,21.3 1 1
4+
github.com/containeroo/resolver/env.go:22.2,22.17 1 1
5+
github.com/containeroo/resolver/file.go:22.70,27.16 4 1
6+
github.com/containeroo/resolver/file.go:27.16,29.3 1 1
7+
github.com/containeroo/resolver/file.go:30.2,32.19 2 1
8+
github.com/containeroo/resolver/file.go:32.19,34.3 1 1
9+
github.com/containeroo/resolver/file.go:37.2,38.16 2 1
10+
github.com/containeroo/resolver/file.go:38.16,40.3 1 0
11+
github.com/containeroo/resolver/file.go:41.2,41.45 1 1
12+
github.com/containeroo/resolver/file.go:45.65,47.21 2 1
13+
github.com/containeroo/resolver/file.go:47.21,50.58 3 1
14+
github.com/containeroo/resolver/file.go:50.58,52.4 1 1
15+
github.com/containeroo/resolver/file.go:54.2,54.76 1 1
16+
github.com/containeroo/resolver/ini.go:23.61,28.16 4 1
17+
github.com/containeroo/resolver/ini.go:28.16,30.3 1 1
18+
github.com/containeroo/resolver/ini.go:32.2,32.19 1 1
19+
github.com/containeroo/resolver/ini.go:32.19,35.17 2 1
20+
github.com/containeroo/resolver/ini.go:35.17,37.4 1 0
21+
github.com/containeroo/resolver/ini.go:38.3,38.46 1 1
22+
github.com/containeroo/resolver/ini.go:42.2,44.21 3 1
23+
github.com/containeroo/resolver/ini.go:44.21,48.3 2 1
24+
github.com/containeroo/resolver/ini.go:48.8,51.3 2 1
25+
github.com/containeroo/resolver/ini.go:53.2,54.16 2 1
26+
github.com/containeroo/resolver/ini.go:54.16,56.3 1 1
27+
github.com/containeroo/resolver/ini.go:58.2,59.34 2 1
28+
github.com/containeroo/resolver/ini.go:59.34,61.3 1 1
29+
github.com/containeroo/resolver/ini.go:63.2,63.24 1 1
30+
github.com/containeroo/resolver/json.go:21.62,26.16 4 1
31+
github.com/containeroo/resolver/json.go:26.16,28.3 1 1
32+
github.com/containeroo/resolver/json.go:30.2,30.19 1 1
33+
github.com/containeroo/resolver/json.go:30.19,33.3 1 1
34+
github.com/containeroo/resolver/json.go:35.2,36.55 2 1
35+
github.com/containeroo/resolver/json.go:36.55,38.3 1 0
36+
github.com/containeroo/resolver/json.go:40.2,41.16 2 1
37+
github.com/containeroo/resolver/json.go:41.16,43.3 1 1
38+
github.com/containeroo/resolver/json.go:45.2,46.9 2 1
39+
github.com/containeroo/resolver/json.go:46.9,50.3 2 1
40+
github.com/containeroo/resolver/json.go:51.2,51.20 1 1
41+
github.com/containeroo/resolver/resolver.go:37.52,38.42 1 1
42+
github.com/containeroo/resolver/resolver.go:38.42,39.39 1 1
43+
github.com/containeroo/resolver/resolver.go:39.39,41.4 1 1
44+
github.com/containeroo/resolver/resolver.go:43.2,43.19 1 1
45+
github.com/containeroo/resolver/slices.go:12.50,14.2 1 1
46+
github.com/containeroo/resolver/slices.go:26.73,28.26 2 1
47+
github.com/containeroo/resolver/slices.go:28.26,30.17 2 1
48+
github.com/containeroo/resolver/slices.go:30.17,32.4 1 1
49+
github.com/containeroo/resolver/slices.go:33.3,33.23 1 1
50+
github.com/containeroo/resolver/slices.go:35.2,35.17 1 1
51+
github.com/containeroo/resolver/testutils.go:5.42,8.2 2 1
52+
github.com/containeroo/resolver/toml.go:22.62,27.16 4 1
53+
github.com/containeroo/resolver/toml.go:27.16,29.3 1 1
54+
github.com/containeroo/resolver/toml.go:32.2,33.64 2 1
55+
github.com/containeroo/resolver/toml.go:33.64,35.3 1 1
56+
github.com/containeroo/resolver/toml.go:38.2,39.55 2 1
57+
github.com/containeroo/resolver/toml.go:39.55,41.3 1 0
58+
github.com/containeroo/resolver/toml.go:43.2,43.19 1 1
59+
github.com/containeroo/resolver/toml.go:43.19,45.3 1 1
60+
github.com/containeroo/resolver/toml.go:47.2,48.16 2 1
61+
github.com/containeroo/resolver/toml.go:48.16,50.3 1 1
62+
github.com/containeroo/resolver/toml.go:52.2,52.36 1 1
63+
github.com/containeroo/resolver/toml.go:52.36,54.3 1 1
64+
github.com/containeroo/resolver/toml.go:56.2,57.16 2 1
65+
github.com/containeroo/resolver/toml.go:57.16,59.3 1 0
66+
github.com/containeroo/resolver/toml.go:61.2,61.48 1 1
67+
github.com/containeroo/resolver/utils.go:10.53,13.15 3 1
68+
github.com/containeroo/resolver/utils.go:13.15,15.3 1 1
69+
github.com/containeroo/resolver/utils.go:16.2,16.47 1 1
70+
github.com/containeroo/resolver/utils.go:31.57,33.25 2 1
71+
github.com/containeroo/resolver/utils.go:33.25,34.33 1 1
72+
github.com/containeroo/resolver/utils.go:35.23,38.11 2 1
73+
github.com/containeroo/resolver/utils.go:38.11,40.5 1 1
74+
github.com/containeroo/resolver/utils.go:41.4,41.17 1 1
75+
github.com/containeroo/resolver/utils.go:43.14,46.18 2 1
76+
github.com/containeroo/resolver/utils.go:46.18,48.5 1 1
77+
github.com/containeroo/resolver/utils.go:49.4,49.35 1 1
78+
github.com/containeroo/resolver/utils.go:49.35,51.5 1 1
79+
github.com/containeroo/resolver/utils.go:52.4,52.23 1 1
80+
github.com/containeroo/resolver/utils.go:54.11,56.60 1 1
81+
github.com/containeroo/resolver/utils.go:59.2,59.21 1 1
82+
github.com/containeroo/resolver/utils.go:64.67,65.25 1 1
83+
github.com/containeroo/resolver/utils.go:66.22,68.28 1 1
84+
github.com/containeroo/resolver/utils.go:68.28,70.18 2 1
85+
github.com/containeroo/resolver/utils.go:70.18,72.5 1 0
86+
github.com/containeroo/resolver/utils.go:73.4,73.22 1 1
87+
github.com/containeroo/resolver/utils.go:75.3,75.16 1 1
88+
github.com/containeroo/resolver/utils.go:76.10,78.31 1 1
89+
github.com/containeroo/resolver/utils.go:82.41,84.26 1 1
90+
github.com/containeroo/resolver/utils.go:85.22,86.24 1 1
91+
github.com/containeroo/resolver/utils.go:86.24,88.18 2 1
92+
github.com/containeroo/resolver/utils.go:88.18,90.5 1 0
93+
github.com/containeroo/resolver/utils.go:91.4,91.21 1 1
94+
github.com/containeroo/resolver/utils.go:93.3,93.17 1 1
95+
github.com/containeroo/resolver/utils.go:94.13,95.27 1 1
96+
github.com/containeroo/resolver/utils.go:95.27,97.18 2 1
97+
github.com/containeroo/resolver/utils.go:97.18,99.5 1 0
98+
github.com/containeroo/resolver/utils.go:100.4,100.21 1 1
99+
github.com/containeroo/resolver/utils.go:102.3,102.17 1 1
100+
github.com/containeroo/resolver/utils.go:103.10,104.17 1 1
101+
github.com/containeroo/resolver/yaml.go:16.62,21.16 4 1
102+
github.com/containeroo/resolver/yaml.go:21.16,23.3 1 1
103+
github.com/containeroo/resolver/yaml.go:25.2,26.55 2 1
104+
github.com/containeroo/resolver/yaml.go:26.55,28.3 1 1
105+
github.com/containeroo/resolver/yaml.go:31.2,32.16 2 1
106+
github.com/containeroo/resolver/yaml.go:32.16,34.3 1 0
107+
github.com/containeroo/resolver/yaml.go:36.2,36.19 1 1
108+
github.com/containeroo/resolver/yaml.go:36.19,39.3 1 1
109+
github.com/containeroo/resolver/yaml.go:41.2,42.16 2 1
110+
github.com/containeroo/resolver/yaml.go:42.16,44.3 1 1
111+
github.com/containeroo/resolver/yaml.go:47.2,47.32 1 1
112+
github.com/containeroo/resolver/yaml.go:48.14,49.23 1 1
113+
github.com/containeroo/resolver/yaml.go:50.10,52.47 2 1

resolver.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@ import (
44
"strings"
55
)
66

7-
// Resolver is the interface that different resolvers must implement.
8-
// Each Resolver takes a value (with prefix already removed) and returns the resolved value or an error.
9-
type Resolver interface {
10-
Resolve(value string) (string, error)
11-
}
12-
137
// Prefixes for different resolvers
148
const (
159
envPrefix string = "env:"
@@ -30,8 +24,16 @@ var resolvers = map[string]Resolver{
3024
tomlPrefix: &TOMLResolver{},
3125
}
3226

33-
// ResolveVariable attempts to resolve the given value by checking for known prefixes.
34-
// If no known prefix is found, it returns the value as-is.
27+
// ResolveVariable attempts to resolve a variable string using a registered resolver.
28+
// The function checks for known prefixes such as "env:", "json:", or "file:" and delegates
29+
// to the corresponding resolver. If no known prefix is found, the original value is returned.
30+
//
31+
// Parameters:
32+
// - value: the input string, possibly prefixed with a resolver keyword.
33+
//
34+
// Returns:
35+
// - resolved string if resolved successfully or the original string if no prefix matches.
36+
// - error if resolution fails.
3537
func ResolveVariable(value string) (string, error) {
3638
for prefix, resolver := range resolvers {
3739
if strings.HasPrefix(value, prefix) {

slices.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package resolver
2+
3+
// ResolveSlice resolves a list of strings using ResolveVariable.
4+
// This is a convenience wrapper that applies ResolveVariable to each element.
5+
//
6+
// Parameters:
7+
// - in: a slice of strings to resolve.
8+
//
9+
// Returns:
10+
// - slice of resolved strings.
11+
// - error if any individual resolution fails.
12+
func ResolveSlice(in []string) ([]string, error) {
13+
return MapWithError(in, ResolveVariable)
14+
}
15+
16+
// MapWithError applies a transformation function that may return an error to each item in a slice.
17+
// The operation stops on the first error.
18+
//
19+
// Parameters:
20+
// - in: the input slice of any type T.
21+
// - fn: a function that maps each T to U and may return an error.
22+
//
23+
// Returns:
24+
// - a slice of type U containing all successfully transformed items.
25+
// - error if transformation fails for any item.
26+
func MapWithError[T, U any](in []T, fn func(T) (U, error)) ([]U, error) {
27+
out := make([]U, 0, len(in))
28+
for _, item := range in {
29+
v, err := fn(item)
30+
if err != nil {
31+
return nil, err
32+
}
33+
out = append(out, v)
34+
}
35+
return out, nil
36+
}

slices_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package resolver
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestMapWithError(t *testing.T) {
11+
t.Run("transforms all items", func(t *testing.T) {
12+
in := []string{"a", "b", "c"}
13+
out, err := MapWithError(in, func(s string) (string, error) {
14+
return s + "!", nil
15+
})
16+
assert.NoError(t, err)
17+
assert.Equal(t, []string{"a!", "b!", "c!"}, out)
18+
})
19+
20+
t.Run("returns first error", func(t *testing.T) {
21+
in := []int{1, 2, 3}
22+
errBoom := errors.New("boom")
23+
out, err := MapWithError(in, func(i int) (string, error) {
24+
if i == 2 {
25+
return "", errBoom
26+
}
27+
return "ok", nil
28+
})
29+
assert.Nil(t, out)
30+
assert.ErrorIs(t, err, errBoom)
31+
})
32+
}
33+
34+
func TestResolveSlice(t *testing.T) {
35+
t.Run("resolves env vars in list", func(t *testing.T) {
36+
t.Setenv("FOO", "abc")
37+
t.Setenv("BAR", "def")
38+
39+
in := []string{"env:FOO", "env:BAR"}
40+
out, err := ResolveSlice(in)
41+
assert.NoError(t, err)
42+
assert.Equal(t, []string{"abc", "def"}, out)
43+
})
44+
45+
t.Run("returns error on invalid key", func(t *testing.T) {
46+
in := []string{"env:FOO", "env:DOES_NOT_EXIST"}
47+
t.Setenv("FOO", "abc")
48+
49+
out, err := ResolveSlice(in)
50+
assert.Nil(t, out)
51+
assert.Error(t, err)
52+
})
53+
}

types.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package resolver
2+
3+
// Resolver is the interface that different resolvers must implement.
4+
// Each Resolver takes a value (with prefix already removed) and returns the resolved value or an error.
5+
type Resolver interface {
6+
Resolve(value string) (string, error)
7+
}

0 commit comments

Comments
 (0)