Skip to content

Commit c095b9c

Browse files
authored
Allow noinit to apply to slices, maps, and unsafe pointers (#83)
Previously, this would throw an error. Fixes GH-82.
1 parent bddf2fa commit c095b9c

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,8 @@ export APP_MYVAR="foo"
305305
306306
## Initialization
307307
308-
By default, all pointer fields are initialized (allocated) so they are not
309-
`nil`. To disable this behavior, use the tag the field as `noinit`:
308+
By default, all pointers, slices, and maps are initialized (allocated) so they
309+
are not `nil`. To disable this behavior, use the tag the field as `noinit`:
310310
311311
```go
312312
type MyStruct struct {
@@ -332,8 +332,8 @@ type ChildConfig struct {
332332
}
333333
```
334334
335-
The `noinit` tag is only applicable for pointer fields. Putting the tag on a
336-
non-struct-pointer will return an error.
335+
The `noinit` tag is only applicable for pointer, slice, and map fields. Putting
336+
the tag on a different type will return an error.
337337
338338
339339
## Extension

envconfig.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,11 @@ func processWith(ctx context.Context, i interface{}, l Lookuper, parentNoInit bo
301301
}
302302

303303
// NoInit is only permitted on pointers.
304-
if opts.NoInit && ef.Kind() != reflect.Ptr {
304+
if opts.NoInit &&
305+
ef.Kind() != reflect.Ptr &&
306+
ef.Kind() != reflect.Slice &&
307+
ef.Kind() != reflect.Map &&
308+
ef.Kind() != reflect.UnsafePointer {
305309
return fmt.Errorf("%s: %w", tf.Name, ErrNoInitNotPtr)
306310
}
307311
shouldNotInit := opts.NoInit || parentNoInit

envconfig_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"strings"
2727
"testing"
2828
"time"
29+
"unsafe"
2930

3031
"github.com/google/go-cmp/cmp"
3132
)
@@ -2227,6 +2228,42 @@ func TestProcessWith(t *testing.T) {
22272228
"FIELD2": "5",
22282229
}),
22292230
},
2231+
{
2232+
name: "noinit/map",
2233+
input: &struct {
2234+
Field map[string]string `env:"FIELD, noinit"`
2235+
}{},
2236+
exp: &struct {
2237+
Field map[string]string `env:"FIELD, noinit"`
2238+
}{
2239+
Field: nil,
2240+
},
2241+
lookuper: MapLookuper(nil),
2242+
},
2243+
{
2244+
name: "noinit/slice",
2245+
input: &struct {
2246+
Field []string `env:"FIELD, noinit"`
2247+
}{},
2248+
exp: &struct {
2249+
Field []string `env:"FIELD, noinit"`
2250+
}{
2251+
Field: nil,
2252+
},
2253+
lookuper: MapLookuper(nil),
2254+
},
2255+
{
2256+
name: "noinit/unsafe_pointer",
2257+
input: &struct {
2258+
Field unsafe.Pointer `env:"FIELD, noinit"`
2259+
}{},
2260+
exp: &struct {
2261+
Field unsafe.Pointer `env:"FIELD, noinit"`
2262+
}{
2263+
Field: nil,
2264+
},
2265+
lookuper: MapLookuper(nil),
2266+
},
22302267
{
22312268
name: "noinit/error_not_ptr",
22322269
input: &struct {

0 commit comments

Comments
 (0)