Skip to content

Commit

Permalink
export less from the callback handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mailund committed Jul 2, 2021
1 parent 6f4b9a2 commit 728bc6e
Showing 1 changed file with 63 additions and 45 deletions.
108 changes: 63 additions & 45 deletions internal/vals/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@ import (
// Function callbacks are special values; we don't need to generate them
// since it is easier just to write the little code there is in the first place
type (
FuncNoValue func() error // FuncNoValue wraps functions that do not take parameter arguments
FuncValue func(string) error // FuncValue wraps functions with a single string argument
VariadicFuncValue func([]string) error // VariadicFuncValue wraps functions with string slice argument
// FuncNoValue wraps functions that do not take parameter arguments
FuncNoValue func() error
// FuncValue wraps functions with a single string argument
FuncValue func(string) error
// VariadicFuncValue wraps functions with string slice argument
VariadicFuncValue func([]string) error
)

func (f FuncNoValue) Set(_ string) error { return f() } // Set implements the PosValue/FlagValue interface
func (f FuncNoValue) String() string { return "" } // String implements the FlagValue interface
func (f FuncNoValue) NoValueFlag() bool { return true } // NoValueFlag implements the no values interface
// Set implements the PosValue/FlagValue interface
func (f FuncNoValue) Set(_ string) error { return f() }

// String implements the FlagValue interface
func (f FuncNoValue) String() string { return "" }

// NoValueFlag implements the no values interface
func (f FuncNoValue) NoValueFlag() bool { return true }

// Validate implements the validator interface and checks that callbacks are not nil.
func (f FuncNoValue) Validate(bool) error { // FIXME: the validators are the same, but need generics to join them
Expand All @@ -27,8 +35,13 @@ func (f FuncNoValue) Validate(bool) error { // FIXME: the validators are the sam
return nil
}

// Set implements the PosValue/FlagValue interface
func (f FuncValue) Set(x string) error { return f(x) }
func (f FuncValue) String() string { return "" }

// String implements the FlagValue interface
func (f FuncValue) String() string { return "" }

// Validate implements the validator interface and checks that callbacks are not nil.
func (f FuncValue) Validate(bool) error {
if f == nil {
return interfaces.SpecErrorf("callbacks cannot be nil")
Expand All @@ -37,7 +50,10 @@ func (f FuncValue) Validate(bool) error {
return nil
}

// Set implements the PosValue/FlagValue interface
func (f VariadicFuncValue) Set(x []string) error { return f(x) }

// Validate implements the validator interface and checks that callbacks are not nil.
func (f VariadicFuncValue) Validate(bool) error {
if f == nil {
return interfaces.SpecErrorf("callbacks cannot be nil")
Expand All @@ -47,85 +63,87 @@ func (f VariadicFuncValue) Validate(bool) error {
}

type (
NCB = func()
NCBI = func(interface{})
NCBE = func() error
NCBIE = func(interface{}) error
ncb = func()
ncbi = func(interface{})
ncbe = func() error
ncbei = func(interface{}) error

CB = func(string) error
CBI = func(string, interface{}) error
cb = func(string) error
cbi = func(string, interface{}) error

VCB = func([]string) error
VCBI = func([]string, interface{}) error
vcb = func([]string) error
vcbi = func([]string, interface{}) error

CallbackWrapper func(*reflect.Value, interface{}) interfaces.FlagValue
VariadicCallbackWrapper func(*reflect.Value, interface{}) interfaces.VariadicValue
callbackWrapper func(*reflect.Value, interface{}) interfaces.FlagValue
variadicCallbackWrapper func(*reflect.Value, interface{}) interfaces.VariadicValue
)

func NCBConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(NCB) // If we call this func, we know we have the right type
func ncbConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(ncb) // If we call this func, we know we have the right type
return FuncNoValue(func() error { f(); return nil })
}

func NCBIConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(NCBI) // If we call this func, we know we have the right type
func ncbiConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(ncbi) // If we call this func, we know we have the right type
return FuncNoValue(func() error { f(i); return nil })
}

func NCBEConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(NCBE) // If we call this func, we know we have the right type
func ncbeConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(ncbe) // If we call this func, we know we have the right type
return FuncNoValue(f)
}

func NCBIEConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(NCBIE) // If we call this func, we know we have the right type
func ncbeiConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(ncbei) // If we call this func, we know we have the right type
return FuncNoValue(func() error { return f(i) })
}

func CBConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(CB) // If we call this func, we know we have the right type
func cbConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(cb) // If we call this func, we know we have the right type
return FuncValue(f)
}

func CBIConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(CBI) // If we call this func, we know we have the right type
func cbiConstructor(val *reflect.Value, i interface{}) interfaces.FlagValue {
f, _ := val.Interface().(cbi) // If we call this func, we know we have the right type
return FuncValue(func(x string) error { return f(x, i) })
}

func VCBConstructor(val *reflect.Value, i interface{}) interfaces.VariadicValue {
f, _ := val.Interface().(VCB) // If we call this func, we know we have the right type
func vcbConstructor(val *reflect.Value, i interface{}) interfaces.VariadicValue {
f, _ := val.Interface().(vcb) // If we call this func, we know we have the right type
return VariadicFuncValue(f)
}

func VCBIConstructor(val *reflect.Value, i interface{}) interfaces.VariadicValue {
f, _ := val.Interface().(VCBI) // If we call this func, we know we have the right type
func vcbiConstructor(val *reflect.Value, i interface{}) interfaces.VariadicValue {
f, _ := val.Interface().(vcbi) // If we call this func, we know we have the right type
return VariadicFuncValue(func(x []string) error { return f(x, i) })
}

var CallbackWrappers = map[reflect.Type]CallbackWrapper{
reflect.TypeOf(NCB(nil)): NCBConstructor,
reflect.TypeOf(NCBI(nil)): NCBIConstructor,
reflect.TypeOf(NCBE(nil)): NCBEConstructor,
reflect.TypeOf(NCBIE(nil)): NCBIEConstructor,
reflect.TypeOf(CB(nil)): CBConstructor,
reflect.TypeOf(CBI(nil)): CBIConstructor,
var callbackWrappers = map[reflect.Type]callbackWrapper{
reflect.TypeOf(ncb(nil)): ncbConstructor,
reflect.TypeOf(ncbi(nil)): ncbiConstructor,
reflect.TypeOf(ncbe(nil)): ncbeConstructor,
reflect.TypeOf(ncbei(nil)): ncbeiConstructor,
reflect.TypeOf(cb(nil)): cbConstructor,
reflect.TypeOf(cbi(nil)): cbiConstructor,
}

var VariadicCallbackWrappers = map[reflect.Type]VariadicCallbackWrapper{
reflect.TypeOf(VCB(nil)): VCBConstructor,
reflect.TypeOf(VCBI(nil)): VCBIConstructor,
var variadicCallbackWrappers = map[reflect.Type]variadicCallbackWrapper{
reflect.TypeOf(vcb(nil)): vcbConstructor,
reflect.TypeOf(vcbi(nil)): vcbiConstructor,
}

// AsCallback returns a value as a wrapped callback function
func AsCallback(val *reflect.Value, i interface{}) interfaces.FlagValue {
if wrap, ok := CallbackWrappers[val.Type()]; ok {
if wrap, ok := callbackWrappers[val.Type()]; ok {
return wrap(val, i)
}

return nil // couldn't convert
}

// AsVariadicCallback returns a value as a wrapped variadic callback function
func AsVariadicCallback(val *reflect.Value, i interface{}) interfaces.VariadicValue {
if wrap, ok := VariadicCallbackWrappers[val.Type()]; ok {
if wrap, ok := variadicCallbackWrappers[val.Type()]; ok {
return wrap(val, i)
}

Expand Down

0 comments on commit 728bc6e

Please sign in to comment.