package node import ( "reflect" ) // Option is a functional option which can be used with the New function to // change how the node is constructed // // Options are applied in sequence type Option func(*settings) error // Options groups multiple options into one func Options(opts ...Option) Option { return func(s *settings) error { for _, opt := range opts { if err := opt(s); err != nil { return err } } return nil } } // Error is a special option which returns an error when applied func Error(err error) Option { return func(_ *settings) error { return err } } func applyIf(check func(s *settings) bool, opts ...Option) Option { return func(s *settings) error { if check(s) { return Options(opts...)(s) } return nil } } // from go-ipfs // as casts input constructor to a given interface (if a value is given, it // wraps it into a constructor). // // Note: this method may look like a hack, and in fact it is one. // This is here only because https://github.com/uber-go/fx/issues/673 wasn't // released yet // // Note 2: when making changes here, make sure this method stays at // 100% coverage. This makes it less likely it will be terribly broken func as(in interface{}, as interface{}) interface{} { outType := reflect.TypeOf(as) if outType.Kind() != reflect.Ptr { panic("outType is not a pointer") } if reflect.TypeOf(in).Kind() != reflect.Func { ctype := reflect.FuncOf(nil, []reflect.Type{outType.Elem()}, false) return reflect.MakeFunc(ctype, func(args []reflect.Value) (results []reflect.Value) { out := reflect.New(outType.Elem()) out.Elem().Set(reflect.ValueOf(in)) return []reflect.Value{out.Elem()} }).Interface() } inType := reflect.TypeOf(in) ins := make([]reflect.Type, inType.NumIn()) outs := make([]reflect.Type, inType.NumOut()) for i := range ins { ins[i] = inType.In(i) } outs[0] = outType.Elem() for i := range outs[1:] { outs[i+1] = inType.Out(i + 1) } ctype := reflect.FuncOf(ins, outs, false) return reflect.MakeFunc(ctype, func(args []reflect.Value) (results []reflect.Value) { outs := reflect.ValueOf(in).Call(args) out := reflect.New(outType.Elem()) out.Elem().Set(outs[0]) outs[0] = out.Elem() return outs }).Interface() }