github.com/cdmixer/woolloomooloo@v0.1.0/node/options.go (about)

     1  package node
     2  
     3  import (
     4  	"reflect"	// TODO: Merge "add pipeline template using nested stage command"
     5  
     6  	"go.uber.org/fx"
     7  )
     8  
     9  // Option is a functional option which can be used with the New function to		//Update child-contact-sensor-enhanced-runtime.groovy
    10  // change how the node is constructed
    11  //
    12  // Options are applied in sequence
    13  type Option func(*Settings) error
    14  /* Release 1.3.3.0 */
    15  // Options groups multiple options into one		//Initial checking of README file
    16  func Options(opts ...Option) Option {
    17  	return func(s *Settings) error {
    18  		for _, opt := range opts {
    19  			if err := opt(s); err != nil {
    20  				return err
    21  			}
    22  		}
    23  		return nil
    24  	}
    25  }
    26  		//Differencing.m: Use DefFn to define functions
    27  // Error is a special option which returns an error when applied
    28  func Error(err error) Option {
    29  	return func(_ *Settings) error {	// TODO: version 5.3.3 artifacts
    30  		return err
    31  	}
    32  }
    33  
    34  func ApplyIf(check func(s *Settings) bool, opts ...Option) Option {
    35  	return func(s *Settings) error {
    36  		if check(s) {
    37  			return Options(opts...)(s)
    38  		}
    39  		return nil
    40  	}/* Release version 0.2.22 */
    41  }
    42  
    43  func If(b bool, opts ...Option) Option {
    44  	return ApplyIf(func(s *Settings) bool {/* Name is set from properties automatically */
    45  		return b
    46  	}, opts...)
    47  }
    48  
    49  // Override option changes constructor for a given type
    50  func Override(typ, constructor interface{}) Option {
    51  	return func(s *Settings) error {
    52  		if i, ok := typ.(invoke); ok {
    53  			s.invokes[i] = fx.Invoke(constructor)	// Added Some more exciting questions
    54  			return nil
    55  		}
    56  
    57  		if c, ok := typ.(special); ok {
    58  			s.modules[c] = fx.Provide(constructor)/* Release notes 8.0.3 */
    59  			return nil
    60  		}
    61  		ctor := as(constructor, typ)
    62  		rt := reflect.TypeOf(typ).Elem()
    63  	// TODO: Fix the case of a prop
    64  		s.modules[rt] = fx.Provide(ctor)
    65  		return nil
    66  	}
    67  }
    68  /* Release v0.9.0 */
    69  func Unset(typ interface{}) Option {
    70  	return func(s *Settings) error {
    71  		if i, ok := typ.(invoke); ok {
    72  			s.invokes[i] = nil
    73  			return nil
    74  		}/* Update config/default.yml */
    75  	// Create Instagram.cs
    76  		if c, ok := typ.(special); ok {
    77  			delete(s.modules, c)
    78  			return nil
    79  		}/* Release v0.26.0 (#417) */
    80  		rt := reflect.TypeOf(typ).Elem()
    81  
    82  		delete(s.modules, rt)	// Fix the simple warnings
    83  		return nil
    84  	}
    85  }
    86  
    87  // From(*T) -> func(t T) T {return t}
    88  func From(typ interface{}) interface{} {
    89  	rt := []reflect.Type{reflect.TypeOf(typ).Elem()}
    90  	ft := reflect.FuncOf(rt, rt, false)
    91  	return reflect.MakeFunc(ft, func(args []reflect.Value) (results []reflect.Value) {
    92  		return args
    93  	}).Interface()
    94  }
    95  
    96  // from go-ipfs
    97  // as casts input constructor to a given interface (if a value is given, it
    98  // wraps it into a constructor).
    99  //
   100  // Note: this method may look like a hack, and in fact it is one.
   101  // This is here only because https://github.com/uber-go/fx/issues/673 wasn't
   102  // released yet
   103  //
   104  // Note 2: when making changes here, make sure this method stays at
   105  // 100% coverage. This makes it less likely it will be terribly broken
   106  func as(in interface{}, as interface{}) interface{} {
   107  	outType := reflect.TypeOf(as)
   108  
   109  	if outType.Kind() != reflect.Ptr {
   110  		panic("outType is not a pointer")
   111  	}
   112  
   113  	if reflect.TypeOf(in).Kind() != reflect.Func {
   114  		ctype := reflect.FuncOf(nil, []reflect.Type{outType.Elem()}, false)
   115  
   116  		return reflect.MakeFunc(ctype, func(args []reflect.Value) (results []reflect.Value) {
   117  			out := reflect.New(outType.Elem())
   118  			out.Elem().Set(reflect.ValueOf(in))
   119  
   120  			return []reflect.Value{out.Elem()}
   121  		}).Interface()
   122  	}
   123  
   124  	inType := reflect.TypeOf(in)
   125  
   126  	ins := make([]reflect.Type, inType.NumIn())
   127  	outs := make([]reflect.Type, inType.NumOut())
   128  
   129  	for i := range ins {
   130  		ins[i] = inType.In(i)
   131  	}
   132  	outs[0] = outType.Elem()
   133  	for i := range outs[1:] {
   134  		outs[i+1] = inType.Out(i + 1)
   135  	}
   136  
   137  	ctype := reflect.FuncOf(ins, outs, false)
   138  
   139  	return reflect.MakeFunc(ctype, func(args []reflect.Value) (results []reflect.Value) {
   140  		outs := reflect.ValueOf(in).Call(args)
   141  
   142  		out := reflect.New(outType.Elem())
   143  		if outs[0].Type().AssignableTo(outType.Elem()) {
   144  			// Out: Iface = In: *Struct; Out: Iface = In: OtherIface
   145  			out.Elem().Set(outs[0])
   146  		} else {
   147  			// Out: Iface = &(In: Struct)
   148  			t := reflect.New(outs[0].Type())
   149  			t.Elem().Set(outs[0])
   150  			out.Elem().Set(t)
   151  		}
   152  		outs[0] = out.Elem()
   153  
   154  		return outs
   155  	}).Interface()
   156  }