|
@ -1,6 +1,7 @@ |
|
|
package config |
|
|
package config |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"errors" |
|
|
"fmt" |
|
|
"fmt" |
|
|
"reflect" |
|
|
"reflect" |
|
|
"runtime" |
|
|
"runtime" |
|
@ -102,6 +103,7 @@ func makeConstructor( |
|
|
tpt interface{}, |
|
|
tpt interface{}, |
|
|
tptType reflect.Type, |
|
|
tptType reflect.Type, |
|
|
argTypes map[reflect.Type]constructor, |
|
|
argTypes map[reflect.Type]constructor, |
|
|
|
|
|
opts ...interface{}, |
|
|
) (func(host.Host, *tptu.Upgrader, connmgr.ConnectionGater) (interface{}, error), error) { |
|
|
) (func(host.Host, *tptu.Upgrader, connmgr.ConnectionGater) (interface{}, error), error) { |
|
|
v := reflect.ValueOf(tpt) |
|
|
v := reflect.ValueOf(tpt) |
|
|
// avoid panicing on nil/zero value.
|
|
|
// avoid panicing on nil/zero value.
|
|
@ -123,17 +125,24 @@ func makeConstructor( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return func(h host.Host, u *tptu.Upgrader, cg connmgr.ConnectionGater) (interface{}, error) { |
|
|
return func(h host.Host, u *tptu.Upgrader, cg connmgr.ConnectionGater) (interface{}, error) { |
|
|
arguments := make([]reflect.Value, len(argConstructors)) |
|
|
arguments := make([]reflect.Value, 0, len(argConstructors)+len(opts)) |
|
|
for i, makeArg := range argConstructors { |
|
|
for i, makeArg := range argConstructors { |
|
|
if arg := makeArg(h, u, cg); arg != nil { |
|
|
if arg := makeArg(h, u, cg); arg != nil { |
|
|
arguments[i] = reflect.ValueOf(arg) |
|
|
arguments = append(arguments, reflect.ValueOf(arg)) |
|
|
} else { |
|
|
} else { |
|
|
// ValueOf an un-typed nil yields a zero reflect
|
|
|
// ValueOf an un-typed nil yields a zero reflect
|
|
|
// value. However, we _want_ the zero value of
|
|
|
// value. However, we _want_ the zero value of
|
|
|
// the _type_.
|
|
|
// the _type_.
|
|
|
arguments[i] = reflect.Zero(t.In(i)) |
|
|
arguments = append(arguments, reflect.Zero(t.In(i))) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
for _, opt := range opts { |
|
|
|
|
|
// don't panic on nil options
|
|
|
|
|
|
if opt == nil { |
|
|
|
|
|
return nil, errors.New("expected a transport option, got nil") |
|
|
|
|
|
} |
|
|
|
|
|
arguments = append(arguments, reflect.ValueOf(opt)) |
|
|
|
|
|
} |
|
|
return callConstructor(v, arguments) |
|
|
return callConstructor(v, arguments) |
|
|
}, nil |
|
|
}, nil |
|
|
} |
|
|
} |
|
|