Skip to content

Commit

Permalink
added support for *url.URL fields
Browse files Browse the repository at this point in the history
replaced golang.org with pkg.go.dev links in README
  • Loading branch information
JeremyLoy committed Nov 18, 2021
1 parent 17bdd6d commit bf76123
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 6 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ err := config.FromEnv().To(&c)

It's just simple, pure stdlib.

* A field's type determines what [strconv](https://golang.org/pkg/strconv/) function is called.
* All string conversion rules are as defined in the [strconv](https://golang.org/pkg/strconv/) package
* time.Duration follows the same parsing rules as [time.ParseDuration](https://golang.org/pkg/time#ParseDuration)
* A field's type determines what [strconv](https://pkg.go.dev/strconv) function is called.
* All string conversion rules are as defined in the [strconv](https://pkg.go.dev/strconv) package
* `time.Duration` follows the same parsing rules as [time.ParseDuration](https://pkg.go.dev/time#ParseDuration)
* `*net.URL` follows the same parsing rules as [url.Parse](https://pkg.go.dev/net/url#URL.Parse)
* NOTE: `*net.URL` fields on the struct **must** be a pointer
* If chaining multiple data sources, data sets are merged.
Later values override previous values.
```go
Expand Down Expand Up @@ -70,3 +72,4 @@ Feel free to use it on its own, or alongside other libraries.
* No maps. The only feature of maps not handled by structs for this usecase is dynamic keys.

* No pointer members. If you really need one, just take the address of parts of your struct.
* One exception is `*url.URL`, which is explicitly a pointer for ease of use, matching the `url` package conventions
1 change: 1 addition & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Builder struct {
// * all int, uint, float variants
// * bool, struct, string
// * time.Duration
// * \*url.URL
// * slice of any of the above, except for []struct{}
// It returns an error if:
// * struct contains unsupported fields (pointers, maps, slice of structs, channels, arrays, funcs, interfaces, complex)
Expand Down
9 changes: 9 additions & 0 deletions api_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config_test

import (
"net/url"
"os"
"reflect"
"strings"
Expand Down Expand Up @@ -29,6 +30,12 @@ func Test_Api(t *testing.T) {
K string
L time.Duration
M int8
U *url.URL
}
wantUrl := "https://google.com/search?q=golang"
wantUrlParsed, err := url.Parse(wantUrl)
if err != nil {
t.Fatalf("could not parse wanted URL: %v", err)
}

file, err := os.CreateTemp("", "testenv")
Expand All @@ -54,6 +61,7 @@ func Test_Api(t *testing.T) {
"I=", // should NOT log I as there is no way to tell if it is missing or deliberately empty
"L=8h",
"M=128", // should fail as it is out of bounds for an int8
"U=" + wantUrl,
}, "\n")
_, err = file.Write([]byte(testData))
if err != nil {
Expand Down Expand Up @@ -87,6 +95,7 @@ func Test_Api(t *testing.T) {
K: "hardcoded",
L: eightHours,
M: 0,
U: wantUrlParsed,
}
wantError := "config: the following fields had errors: [file[nonexistfile] g[1] h m]"

Expand Down
9 changes: 6 additions & 3 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
// var c MyConfig
// config.FromEnv().To(&c)
//
// A field's type determines what https://golang.org/pkg/strconv/ function is called.
// A field's type determines what https://pkg.go.dev/strconv function is called.
//
// All string conversion rules are as defined in the https://golang.org/pkg/strconv/ package.
// All string conversion rules are as defined in the https://pkg.go.dev/strconv package.
//
// time.Duration follows the same parsing rules as https://golang.org/pkg/time#ParseDuration
// time.Duration follows the same parsing rules as https://pkg.go.dev/time#ParseDuration
//
// *net.URL follows the same parsing rules as https://pkg.go.dev/net/url#URL.Parse
// NOTE: `*net.URL` fields on the struct **must** be a pointer
//
// If chaining multiple data sources, data sets are merged.
//
Expand Down
7 changes: 7 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"fmt"
"net/url"
"reflect"
"strconv"
"strings"
Expand Down Expand Up @@ -122,8 +123,14 @@ func convertAndSetValue(settable reflect.Value, s string) bool {
u uint64
b bool
f float64
url *url.URL
)
switch settableValue.Kind() {
case reflect.Ptr: // only one pointer type is handled at the moment, *url.URL
url, err = url.Parse(s)
if err == nil {
settableValue.Set(reflect.ValueOf(url))
}
case reflect.String:
settableValue.SetString(s)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
Expand Down

0 comments on commit bf76123

Please sign in to comment.