diff --git a/mapper.go b/mapper.go index 863478e..e6c6ad7 100644 --- a/mapper.go +++ b/mapper.go @@ -3,6 +3,7 @@ package kong import ( "fmt" "math/bits" + "net/url" "os" "reflect" "strconv" @@ -162,10 +163,11 @@ func (r *Registry) RegisterDefaults() *Registry { return nil })). RegisterKind(reflect.Bool, boolMapper{}). - RegisterType(reflect.TypeOf(time.Time{}), timeDecoder()). - RegisterType(reflect.TypeOf(time.Duration(0)), durationDecoder()). RegisterKind(reflect.Slice, sliceDecoder(r)). RegisterKind(reflect.Map, mapDecoder(r)). + RegisterType(reflect.TypeOf(time.Time{}), timeDecoder()). + RegisterType(reflect.TypeOf(time.Duration(0)), durationDecoder()). + RegisterType(reflect.TypeOf(&url.URL{}), urlMapper()). RegisterName("path", pathMapper(r)). RegisterName("existingfile", existingFileMapper(r)). RegisterName("existingdir", existingDirMapper(r)) @@ -360,6 +362,17 @@ func existingDirMapper(r *Registry) MapperFunc { } } +func urlMapper() MapperFunc { + return func(ctx *DecodeContext, target reflect.Value) error { + url, err := url.Parse(ctx.Scan.PopValue("url")) + if err != nil { + return err + } + target.Set(reflect.ValueOf(url)) + return nil + } +} + // SplitEscaped splits a string on a separator. // // It differs from strings.Split() in that the separator can exist in a field by escaping it with a \. eg. diff --git a/mapper_test.go b/mapper_test.go index 978a23a..2715246 100644 --- a/mapper_test.go +++ b/mapper_test.go @@ -1,6 +1,7 @@ package kong import ( + "net/url" "reflect" "testing" "time" @@ -95,3 +96,15 @@ func TestMapWithNamedTypes(t *testing.T) { require.NoError(t, err) require.Equal(t, map[string]string{"FIRST": "5s", "SECOND": "10s"}, cli.TypedKey) } + +func TestURLMapper(t *testing.T) { + var cli struct { + URL *url.URL `arg:""` + } + p := mustNew(t, &cli) + _, err := p.Parse([]string{"http://w3.org"}) + require.NoError(t, err) + require.Equal(t, "http://w3.org", cli.URL.String()) + _, err = p.Parse([]string{":foo"}) + require.Error(t, err) +}