Skip to content

Commit

Permalink
feat: ParseAs, ParseAsWithOptions, Must
Browse files Browse the repository at this point in the history
closes #299

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
  • Loading branch information
caarlos0 committed Apr 1, 2024
1 parent fa32ef4 commit 9e164b4
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Expand Up @@ -3,9 +3,9 @@ name: build
on:
push:
branches:
- 'main'
- "main"
tags:
- 'v*'
- "v*"
pull_request:

jobs:
Expand All @@ -18,8 +18,8 @@ jobs:
build:
strategy:
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
go-version: [ oldstable, stable]
os: [ubuntu-latest, macos-latest, windows-latest]
go-version: [1.18, oldstable, stable]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
Expand Down
26 changes: 26 additions & 0 deletions env_generic.go
@@ -0,0 +1,26 @@
//go:build go1.18
// +build go1.18

package env

// ParseAs parses the given struct type containing `env` tags and loads its
// values from environment variables.
func ParseAs[T any]() (T, error) {

Check failure on line 8 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

type parameter requires go1.18 or later (-lang was set to go1.17; check go.mod)

Check failure on line 8 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

predeclared any requires go1.18 or later (-lang was set to go1.17; check go.mod)
var t T
return t, Parse(&t)
}

// ParseWithOptions parses the given struct type containing `env` tags and
// loads its values from environment variables.
func ParseAsWithOptions[T any](opts Options) (T, error) {

Check failure on line 15 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

type parameter requires go1.18 or later (-lang was set to go1.17; check go.mod)

Check failure on line 15 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

predeclared any requires go1.18 or later (-lang was set to go1.17; check go.mod)
var t T
return t, ParseWithOptions(&t, opts)
}

// Must panic is if err is not nil, and returns t otherwise.
func Must[T any](t T, err error) T {

Check failure on line 21 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

type parameter requires go1.18 or later (-lang was set to go1.17; check go.mod)

Check failure on line 21 in env_generic.go

View workflow job for this annotation

GitHub Actions / lint

predeclared any requires go1.18 or later (-lang was set to go1.17; check go.mod)
if err != nil {
panic(err)
}
return t
}
46 changes: 46 additions & 0 deletions env_generic_test.go
@@ -0,0 +1,46 @@
//go:build go1.18
// +build go1.18

package env

import "testing"

type Conf struct {
Foo string `env:"FOO" envDefault:"bar"`
}

func TestParseAs(t *testing.T) {
config, err := ParseAs[Conf]()

Check failure on line 13 in env_generic_test.go

View workflow job for this annotation

GitHub Actions / lint

function instantiation requires go1.18 or later (-lang was set to go1.17; check go.mod)
isNoErr(t, err)
isEqual(t, "bar", config.Foo)
}

func TestParseAsWithOptions(t *testing.T) {
config, err := ParseAsWithOptions[Conf](Options{

Check failure on line 19 in env_generic_test.go

View workflow job for this annotation

GitHub Actions / lint

function instantiation requires go1.18 or later (-lang was set to go1.17; check go.mod)
Environment: map[string]string{
"FOO": "not bar",
},
})
isNoErr(t, err)
isEqual(t, "not bar", config.Foo)
}

type ConfRequired struct {
Foo string `env:"FOO,required"`
}

func TestMust(t *testing.T) {
t.Run("error", func(t *testing.T) {
defer func() {
err := recover()
isErrorWithMessage(t, err.(error), `env: required environment variable "FOO" is not set`)
}()
conf := Must(ParseAs[ConfRequired]())

Check failure on line 38 in env_generic_test.go

View workflow job for this annotation

GitHub Actions / lint

implicit function instantiation requires go1.18 or later (-lang was set to go1.17; check go.mod)
isEqual(t, "", conf.Foo)
})
t.Run("success", func(t *testing.T) {
t.Setenv("FOO", "bar")
conf := Must(ParseAs[ConfRequired]())
isEqual(t, "bar", conf.Foo)
})
}

0 comments on commit 9e164b4

Please sign in to comment.