Skip to content

Commit

Permalink
Merge pull request #55 from rjeczalik/flag-value
Browse files Browse the repository at this point in the history
multiconfig: add partial support for flag.Value
  • Loading branch information
Cihangir committed Dec 5, 2016
2 parents a2dc2f8 + 58dd6d6 commit d41df09
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
45 changes: 45 additions & 0 deletions flag_test.go
@@ -1,6 +1,8 @@
package multiconfig

import (
"flag"
"net/url"
"strings"
"testing"

Expand Down Expand Up @@ -120,6 +122,49 @@ func TestCustomUsageFunc(t *testing.T) {
}
}

type URL struct {
*url.URL
}

var _ flag.Value = (*URL)(nil)

func (u *URL) Set(s string) error {
ur, err := url.Parse(s)
if err != nil {
return err
}
u.URL = ur
return nil
}

type Endpoint struct {
Private *URL `required:"true"`
Public *URL `required:"true"`
}

func TestFlagValueSupport(t *testing.T) {
m := &FlagLoader{}

m.Args = []string{
"-private", "http://127.0.0.1/kloud/kite",
"-public", "http://127.0.0.1/kloud/kite",
}

var e Endpoint

if err := m.Load(&e); err != nil {
t.Fatalf("Load()=%s", err)
}

if e.Private.String() != m.Args[1] {
t.Fatalf("got %q, want %q", e.Private, m.Args[3])
}

if e.Public.String() != m.Args[3] {
t.Fatalf("got %q, want %q", e.Public, m.Args[3])
}
}

// getFlags returns a slice of arguments that can be passed to flag.Parse()
func getFlags(t *testing.T, structName, prefix string) []string {
if structName == "" {
Expand Down
19 changes: 19 additions & 0 deletions multiconfig.go
@@ -1,6 +1,7 @@
package multiconfig

import (
"flag"
"fmt"
"os"
"reflect"
Expand Down Expand Up @@ -114,6 +115,24 @@ func (d *DefaultLoader) MustValidate(conf interface{}) {
// string value in a sane way and is usefulf or environment variables or flags
// which are by nature in string types.
func fieldSet(field *structs.Field, v string) error {
switch f := field.Value().(type) {
case flag.Value:
if v := reflect.ValueOf(field.Value()); v.IsNil() {
typ := v.Type()
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
}

if err := field.Set(reflect.New(typ).Interface()); err != nil {
return err
}

f = field.Value().(flag.Value)
}

return f.Set(v)
}

// TODO: add support for other types
switch field.Kind() {
case reflect.Bool:
Expand Down

0 comments on commit d41df09

Please sign in to comment.