File: builtin.go

package info (click to toggle)
golang-github-anacrolix-tagflag 0.0.0-20180109-2146c8d-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 120 kB
  • sloc: makefile: 2
file content (56 lines) | stat: -rw-r--r-- 1,787 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package tagflag

import (
	"net"
	"net/url"
	"reflect"
	"time"
)

var builtinMarshalers = map[reflect.Type]marshaler{}

// Convenience function to allow adding  marshalers using typed functions.
// marshalFunc is of type func(arg string) T or func(arg string) (T, error),
// where T is the type the function can marshal.
func addBuiltinDynamicMarshaler(marshalFunc interface{}, explicitValueRequired bool) {
	marshalFuncValue := reflect.ValueOf(marshalFunc)
	marshalType := marshalFuncValue.Type().Out(0)
	builtinMarshalers[marshalType] = dynamicMarshaler{
		marshal: func(marshalValue reflect.Value, arg string) error {
			out := marshalFuncValue.Call([]reflect.Value{reflect.ValueOf(arg)})
			marshalValue.Set(out[0])
			if len(out) > 1 {
				i := out[1].Interface()
				if i != nil {
					return i.(error)
				}
			}
			return nil
		},
		explicitValueRequired: explicitValueRequired,
	}
}

func init() {
	// These are some simple builtin types that are nice to be handled without
	// wrappers that implement Marshaler. Note that if they return pointer
	// types, those must be used in the flag struct, because there's no way to
	// know that nothing depends on the address returned.
	addBuiltinDynamicMarshaler(func(urlStr string) (*url.URL, error) {
		return url.Parse(urlStr)
	}, false)
	// Empty strings for this type are valid, so we enforce that the value is
	// explicit (=), so that the user knows what they're getting into.
	addBuiltinDynamicMarshaler(func(s string) (*net.TCPAddr, error) {
		if s == "" {
			return nil, nil
		}
		return net.ResolveTCPAddr("tcp", s)
	}, true)
	addBuiltinDynamicMarshaler(func(s string) (time.Duration, error) {
		return time.ParseDuration(s)
	}, false)
	addBuiltinDynamicMarshaler(func(s string) net.IP {
		return net.ParseIP(s)
	}, false)
}