fo

package module
v1.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 25, 2025 License: MIT Imports: 8 Imported by: 6

README

fo - function calling utilities and controls

tag Go Version GoDoc Build Status Go report Contributors


This project is inspired by samber/lo (A Lodash-style Go library based on Go 1.18+ Generics)

Why this name?

Just followed the naming convention of samber/lo with the f prefix, it stands for function.

🚀 Install

go get github.com/nekomeowww/fo@v1

This library is v1 and follows SemVer strictly.

No breaking changes will be made to exported APIs before v2.0.0.

💡 Usage

You can import fo using:

import (
    "github.com/nekomeowww/fo"
)

Then use one of the helpers below:

name := fo.May(func () (string, error) {
    return "John", nil
})

fmt.Println(name)
// John

Most of the time, the compiler will be able to infer the type so that you can call: fo.May(...).

🤠 Spec

GoDoc: https://godoc.org/github.com/nekomeowww/fo

Global setters:

Function helpers:

Error handling:

SetLogger

Sets the logger for the package.

fo.SetLogger(logrus.New())
SetHandlers

Sets the handlers for the package.

fo.SetHandlers(
    func (err error, v ...any) {
        fmt.Println(err, v...)
    },
    func (err error, v ...any) {
        fmt.Println(err, v...)
    },
)
Invoke

Calls any functions with context.Context control supported and returns the result.

ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)

val, err := fo.Invoke(ctx, func() (string, error) {
    time.Sleep(2 * time.Second)
    return "John", nil
})
// val == ""
// err == context deadline exceeded
Invoke{0->6}

Invoke* has the same behavior as Invoke, but returns multiple values.

func example0() (error) {}
func example1() (int, error) {}
func example2() (int, string, error) {}
func example3() (int, string, time.Date, error) {}
func example4() (int, string, time.Date, bool, error) {}
func example5() (int, string, time.Date, bool, float64, error) {}
func example6() (int, string, time.Date, bool, float64, byte, error) {}

ctx1, cancel1 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel1()

err1 := fo.Invoke0(ctx1, example0())

ctx2, cancel2 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel2()

val1, err1 := fo.Invoke1(ctx1, example1()) // alias to Invoke

ctx3, cancel3 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel3()

val1, val2, err1 := fo.Invoke2(ctx1, example2())

ctx4, cancel4 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel4()

val1, val2, val3, err1 := fo.Invoke3(ctx1, example3())

ctx5, cancel5 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel5()

val1, val2, val3, val4, err1 := fo.Invoke4(ctx1, example4())

ctx6, cancel6 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel6()

val1, val2, val3, val4, val5, err1 := fo.Invoke5(ctx1, example5())

ctx7, cancel7 := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel7()

val1, val2, val3, val4, val5, val6, err1 := fo.Invoke6(ctx1, example6())
InvokeWith

A short cut to Invoke with context.Context that wrapped internally.

val, err := fo.InvokeWith(func() (string, error) {
    time.Sleep(2 * time.Second)
    return "John", nil
}, fo.WithContextTimeout(1*time.Second))
// val == ""
// err == context deadline exceeded
InvokeWith{0->6}

InvokeWith* has the same behavior as InvokeWith, but returns multiple values.

func example0() (error) {}
func example1() (int, error) {}
func example2() (int, string, error) {}
func example3() (int, string, time.Date, error) {}
func example4() (int, string, time.Date, bool, error) {}
func example5() (int, string, time.Date, bool, float64, error) {}
func example6() (int, string, time.Date, bool, float64, byte, error) {}


err1 := fo.InvokeWith0(ctx1, example0(), fo.WithContextTimeout(1*time.Second))


val1, err1 := fo.InvokeWith1(ctx1, example1(), fo.WithContextTimeout(1*time.Second)) // alias to InvokeWith


val1, val2, err1 := fo.InvokeWith2(ctx1, example2(), fo.WithContextTimeout(1*time.Second))


val1, val2, val3, err1 := fo.InvokeWith3(ctx1, example3(), fo.WithContextTimeout(1*time.Second))


val1, val2, val3, val4, err1 := fo.InvokeWith4(ctx1, example4(), fo.WithContextTimeout(1*time.Second))


val1, val2, val3, val4, val5, err1 := fo.InvokeWith5(ctx1, example5(), fo.WithContextTimeout(1*time.Second))


val1, val2, val3, val4, val5, val6, err1 := fo.InvokeWith6(ctx1, example6(), fo.WithContextTimeout(1*time.Second))
InvokeWithTimeout

A short cut to Invoke with context.Context that wrapped internally and defaults to set fo.WithContextTimeout(...).

val, err := fo.InvokeWithTimeout(func() (string, error) {
    time.Sleep(2 * time.Second)
    return "John", nil
}, 1*time.Second)
// val == ""
// err == context deadline exceeded
InvokeWithTimeout{0->6}

InvokeWithTimeout* has the same behavior as InvokeWithTimeout, but returns multiple values.

func example0() (error) {}
func example1() (int, error) {}
func example2() (int, string, error) {}
func example3() (int, string, time.Date, error) {}
func example4() (int, string, time.Date, bool, error) {}
func example5() (int, string, time.Date, bool, float64, error) {}
func example6() (int, string, time.Date, bool, float64, byte, error) {}


err1 := fo.InvokeWithTimeout0(ctx1, example0(), 1*time.Second)


val1, err1 := fo.InvokeWithTimeout1(ctx1, example1(), 1*time.Second) // alias to InvokeWithTimeout


val1, val2, err1 := fo.InvokeWithTimeout2(ctx1, example2(), 1*time.Second)


val1, val2, val3, err1 := fo.InvokeWithTimeout3(ctx1, example3(), 1*time.Second)


val1, val2, val3, val4, err1 := fo.InvokeWithTimeout4(ctx1, example4(), 1*time.Second)


val1, val2, val3, val4, val5, err1 := fo.InvokeWithTimeout5(ctx1, example5(), 1*time.Second)


val1, val2, val3, val4, val5, val6, err1 := fo.InvokeWithTimeout6(ctx1, example6(), 1*time.Second)
May

Wraps a function call and filter out the error values and only returns with the result values.

val := fo.May(time.Parse("2006-01-02", "2022-01-15"))
// 2022-01-15

val := fo.May(time.Parse("2006-01-02", "bad-value"))
// nil
May{0->6}

May* has the same behavior as May, but returns multiple values.

func example0() (error)
func example1() (int, error)
func example2() (int, string, error)
func example3() (int, string, time.Date, error)
func example4() (int, string, time.Date, bool, error)
func example5() (int, string, time.Date, bool, float64, error)
func example6() (int, string, time.Date, bool, float64, byte, error)

fo.May0(example0())
val1 := fo.May1(example1())    // alias to May
val1, val2 := fo.May2(example2())
val1, val2, val3 := fo.May3(example3())
val1, val2, val3, val4 := fo.May4(example4())
val1, val2, val3, val4, val5 := fo.May5(example5())
val1, val2, val3, val4, val5, val6 := fo.May6(example6())

You can wrap functions like func (...) (..., ok bool) with May* and get the result values.

// math.Signbit(float64) bool
fo.May0(math.Signbit(v))

// bytes.Cut([]byte,[]byte) ([]byte, []byte, bool)
before, after := fo.May2(bytes.Cut(s, sep))

You can give context to the panic message by adding some printf-like arguments.

val, ok := any(someVar).(string)
fo.May1(val, ok, "someVar may be a string, got '%s'", val)

list := []int{0, 1, 2}
item := 5
fo.May0(lo.Contains[int](list, item), "'%s' may always contain '%s'", list, item)
...
NewMay

Wraps a function call and filter out the error values and only returns with the result values, behaves just like May(...) and May\*(...), but with customizable handler and error collect instead of using the package level internal handlers. Suitable for in-function and goroutine usage.

may := fo.NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "2022-01-15"))
// 2022-01-15

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
// nil

You could use may.Use(...) to add handlers to the May instance for better error handling.

may := fo.NewMay[time.Time]()
may.Use(func (err error, v ...any) {
    fmt.Printf("error: %s\n", err)
})

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
// error: parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006"

may.Use(...) supports chained calls.

may := fo.NewMay[time.Time]()
    .Use(func (err error, v ...any) {
        fmt.Printf("error from handler 1: %s\n", err)
    })
    .Use(func (err error, v ...any) {
        fmt.Printf("error from handler 2: %s\n", err)
    })
    // multiple handlers will be called in order

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
// error from handler 1: parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006"
// error from handler 2: parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006"

fo ships with some basic handler functions for common error handling.

may := fo.NewMay[string]()
    .Use(fo.WithLoggerHandler(logger)) // log error with logger
    .Use(fo.WithLogFuncHandler(log.Printf)) // log error with log.Printf
NewMay{0->6}

NewMay* has the same behavior as NewMay, but returns multiple values.

may := NewMay2[string, string]()

val1, val2 := may.Invoke(func () (string, bool, error) {
    return "John", true, nil
})
// val1 == "John"
// val2 == true
CollectAsError

Get the collected errors as a single error value from the May instance.

may := fo.NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

err := may.CollectAsError() // error
// this error has been combined with go.uber.org/multierr.Combine(...).
// You can use errors.Is(err, someErr) to check if the error contains some error.
// Or just use multierr.Errors(err) to get the slice of errors.

This function is often useful when you want to return the error value only when all the invocations called / finished instead of checking the error value after each invocation.

may := NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

if err := may.CollectAsError(); err != nil {
    return err
}
CollectAsErrors

Get the collected errors as a errors slice value from the May instance.

may := NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

errs := may.CollectAsErrors() // []error
fmt.Println(errs)
// []errors{
//     parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006",
//     parsing time "bad-value2" as "2006-01-02": cannot parse "bad-value2" as "2006",
// }
HandleErrors

Sometimes you may find out you need a unique way to handle the errors from a May instance, instead of using the injected handlers with Use(...).

may := NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

may.HandleErrors(func(errs []error) {
    fmt.Printf("error: %s\n", errs)
})
// error: [parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006" parsing time "bad-value2" as "2006-01-02": cannot parse "bad-value2" as "2006"]

Or perhaps you could return the collected errors when defering the may.HandleErrors(...) call.

func func1() (err error) {
    may := NewMay[time.Time]()

    defer may.HandleErrors(func(errs []error) {
        err = fmt.Errorf("error: %s\n", errs)
    })

    val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
    val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

    return nil
}

func main() {
    err := func1()
    fmt.Println(err)
}
// error: [parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006" parsing time "bad-value2" as "2006-01-02": cannot parse "bad-value2" as "2006"]
HandleErrorsWithReturn

may.HandleErrorsWithReturn(...) is similar to may.HandleErrors(...), but it returns the handled errors.

may := NewMay[time.Time]()

val := may.Invoke(time.Parse("2006-01-02", "bad-value"))
val2 := may.Invoke(time.Parse("2006-01-02", "bad-value2"))

err := may.HandleErrorsWithReturn(func(err []error) error {
    return fmt.Errorf("error: %s\n", err)
})

fmt.Println(val, val2, err)
// 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC error: [parsing time "bad-value" as "2006-01-02": cannot parse "bad-value" as "2006" parsing time "bad-value2" as "2006-01-02": cannot parse "bad-value2" as "2006"]

TODOs

  • implement more testable examples
  • add playground link to README
  • add benchmark tests
  • maybe use sync.Pool for package level May instances

🤝 Contributing

Helper naming: helpers must be self explanatory and respect standards (other languages, libraries...). Feel free to suggest many names in your contributions.

👪 Other family members of anyo

📝 License

Copyright © 2023 Neko Ayaka.

This project is MIT licensed.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Invoke

func Invoke[R1 any](ctx context.Context, fn func() (R1, error)) (R1, error)

Invoke invokes the callback function and enables to control the context of the callback function with 1 return value.

Example
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*500)
defer cancel()

str, err := Invoke(ctx, func() (int, error) {
	time.Sleep(time.Second)
	return 0, nil
})

fmt.Println(str, err)
Output:
0 context deadline exceeded

func Invoke0

func Invoke0(ctx context.Context, fn func() error) error

Invoke0 has the same behavior as Invoke but without return value.

func Invoke1

func Invoke1[R1 any](ctx context.Context, fn func() (R1, error)) (R1, error)

Invoke1 is an alias of Invoke.

func Invoke2

func Invoke2[R1 any, R2 any](ctx context.Context, fn func() (R1, R2, error)) (R1, R2, error)

Invoke2 has the same behavior as Invoke but with 2 return values.

func Invoke3

func Invoke3[R1 any, R2 any, R3 any](ctx context.Context, fn func() (R1, R2, R3, error)) (R1, R2, R3, error)

Invoke3 has the same behavior as Invoke but with 3 return values.

func Invoke4

func Invoke4[R1 any, R2 any, R3 any, R4 any](ctx context.Context, fn func() (R1, R2, R3, R4, error)) (R1, R2, R3, R4, error)

Invoke4 has the same behavior as Invoke but with 4 return values.

func Invoke5

func Invoke5[R1 any, R2 any, R3 any, R4 any, R5 any](ctx context.Context, fn func() (R1, R2, R3, R4, R5, error)) (R1, R2, R3, R4, R5, error)

Invoke5 has the same behavior as Invoke but with 5 return values.

func Invoke6

func Invoke6[R1 any, R2 any, R3 any, R4 any, R5 any, R6 any](ctx context.Context, fn func() (R1, R2, R3, R4, R5, R6, error)) (R1, R2, R3, R4, R5, R6, error)

Invoke6 has the same behavior as Invoke but with 6 return values.

func InvokeWith added in v1.2.0

func InvokeWith[R1 any](fn func() (R1, error), opts ...CallInvokeWithOption) (R1, error)

InvokeWith invokes the callback function with the CallInvokeWithOption passed in and set for context.Background() as parent context and enables to control the context of the callback function with 1 return value and an error.

Example
str, err := InvokeWith(func() (int, error) {
	time.Sleep(time.Second)
	return 0, nil
}, WithContextTimeout(time.Millisecond*500))

fmt.Println(str, err)
Output:
0 context deadline exceeded

func InvokeWith0 added in v1.2.0

func InvokeWith0(fn func() error, opts ...CallInvokeWithOption) error

InvokeWith0 has the same behavior as InvokeWith but without return value.

func InvokeWith1 added in v1.2.0

func InvokeWith1[R1 any](fn func() (R1, error), opts ...CallInvokeWithOption) (R1, error)

InvokeWith1 is an alias of InvokeWith.

func InvokeWith2 added in v1.2.0

func InvokeWith2[R1 any, R2 any](fn func() (R1, R2, error), opts ...CallInvokeWithOption) (R1, R2, error)

InvokeWith2 has the same behavior as InvokeWith but with 2 return values.

func InvokeWith3 added in v1.2.0

func InvokeWith3[R1 any, R2 any, R3 any](fn func() (R1, R2, R3, error), opts ...CallInvokeWithOption) (R1, R2, R3, error)

InvokeWith3 has the same behavior as InvokeWith but with 3 return values.

func InvokeWith4 added in v1.2.0

func InvokeWith4[R1 any, R2 any, R3 any, R4 any](fn func() (R1, R2, R3, R4, error), opts ...CallInvokeWithOption) (R1, R2, R3, R4, error)

InvokeWith4 has the same behavior as InvokeWith but with 4 return values.

func InvokeWith5 added in v1.2.0

func InvokeWith5[R1 any, R2 any, R3 any, R4 any, R5 any](fn func() (R1, R2, R3, R4, R5, error), opts ...CallInvokeWithOption) (R1, R2, R3, R4, R5, error)

InvokeWith5 has the same behavior as InvokeWith but with 5 return values.

func InvokeWith6 added in v1.2.0

func InvokeWith6[R1 any, R2 any, R3 any, R4 any, R5 any, R6 any](fn func() (R1, R2, R3, R4, R5, R6, error), opts ...CallInvokeWithOption) (R1, R2, R3, R4, R5, R6, error)

InvokeWith6 has the same behavior as InvokeWith but with 6 return values.

func InvokeWithTimeout added in v1.2.0

func InvokeWithTimeout[R1 any](fn func() (R1, error), timeout time.Duration) (R1, error)

InvokeWithTimeout invokes the callback function with the timeout passed in and set for context.Background() as parent context with context.WithTimeout(...) and enables to control the timeout context of the callback function with 1 return value and an error.

Example
str, err := InvokeWithTimeout(func() (int, error) {
	time.Sleep(time.Second)
	return 0, nil
}, time.Millisecond*500)

fmt.Println(str, err)
Output:
0 context deadline exceeded

func InvokeWithTimeout0 added in v1.2.0

func InvokeWithTimeout0(fn func() error, timeout time.Duration) error

InvokeWithTimeout0 has the same behavior as InvokeWithTimeout but without return value.

func InvokeWithTimeout1 added in v1.2.0

func InvokeWithTimeout1[R1 any](fn func() (R1, error), timeout time.Duration) (R1, error)

InvokeWithTimeout1 is an alias of InvokeWithTimeout.

func InvokeWithTimeout2 added in v1.2.0

func InvokeWithTimeout2[R1 any, R2 any](fn func() (R1, R2, error), timeout time.Duration) (R1, R2, error)

InvokeWithTimeout2 has the same behavior as InvokeWithTimeout but with 2 return values.

func InvokeWithTimeout3 added in v1.2.0

func InvokeWithTimeout3[R1 any, R2 any, R3 any](fn func() (R1, R2, R3, error), timeout time.Duration) (R1, R2, R3, error)

InvokeWithTimeout3 has the same behavior as InvokeWithTimeout but with 3 return values.

func InvokeWithTimeout4 added in v1.2.0

func InvokeWithTimeout4[R1 any, R2 any, R3 any, R4 any](fn func() (R1, R2, R3, R4, error), timeout time.Duration) (R1, R2, R3, R4, error)

InvokeWithTimeout4 has the same behavior as InvokeWithTimeout but with 4 return values.

func InvokeWithTimeout5 added in v1.2.0

func InvokeWithTimeout5[R1 any, R2 any, R3 any, R4 any, R5 any](fn func() (R1, R2, R3, R4, R5, error), timeout time.Duration) (R1, R2, R3, R4, R5, error)

InvokeWithTimeout5 has the same behavior as InvokeWithTimeout but with 5 return values.

func InvokeWithTimeout6 added in v1.2.0

func InvokeWithTimeout6[R1 any, R2 any, R3 any, R4 any, R5 any, R6 any](fn func() (R1, R2, R3, R4, R5, R6, error), timeout time.Duration) (R1, R2, R3, R4, R5, R6, error)

InvokeWithTimeout6 has the same behavior as InvokeWithTimeout but with 6 return values.

func May

func May[T any](val T, err any, messageArgs ...any) T

May is a helper that wraps a call to a callback function and then filters out the error from the result and only returns the value. If the error is not nil, it will be handled by handlers registered by SetMayHandlers(...), or be logged by default logging handler.

Example
funcWithError := func() (int, error) {
	return 0, errors.New("something went wrong")
}

funcWithNilErr := func() (int, error) {
	return 42, nil
}

str := May(funcWithError())
str2 := May(funcWithNilErr())

fmt.Println(str)
fmt.Println(str2)
Output:
0
42

func May0

func May0(err any, messageArgs ...any)

May0 has the same behavior as May, but callback returns no variable.

func May1

func May1[T any](t1 T, err any, messageArgs ...any) T

May1 is an alias of May.

func May2

func May2[T1 any, T2 any](t1 T1, t2 T2, err any, messageArgs ...any) (T1, T2)

May2 has the same behavior as May, but callback returns 2 variables.

func May3

func May3[T1 any, T2 any, T3 any](t1 T1, t2 T2, t3 T3, err any, messageArgs ...any) (T1, T2, T3)

May3 has the same behavior as May, but callback returns 3 variables.

func May4

func May4[T1 any, T2 any, T3 any, T4 any](t1 T1, t2 T2, t3 T3, t4 T4, err any, messageArgs ...any) (T1, T2, T3, T4)

May4 has the same behavior as May, but callback returns 4 variables.

func May5

func May5[T1 any, T2 any, T3 any, T4 any, T5 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, err any, messageArgs ...any) (T1, T2, T3, T4, T5)

May5 has the same behavior as May, but callback returns 5 variables.

func May6

func May6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, err any, messageArgs ...any) (T1, T2, T3, T4, T5, T6)

May6 has the same behavior as May, but callback returns 6 variables.

func SetHandlers

func SetHandlers(handler ...MayHandler)

SetHandlers sets the global handlers for May and May* functions.

NOTICE: This function will replace all the global existing handlers on package fo level.

func SetLoggers

func SetLoggers(logger ...Logger)

SetLoggers sets the global loggers for May and May* functions.

NOTICE: This function will replace all the global existing handlers on package fo level.

Types

type CallInvokeWithOption added in v1.2.0

type CallInvokeWithOption struct {
	// contains filtered or unexported fields
}

func WithContextTimeout added in v1.2.0

func WithContextTimeout(timeout time.Duration) CallInvokeWithOption

type Logger

type Logger interface {
	Error(v ...any)
}

type MayHandler

type MayHandler func(err error, messageArgs ...any)

MayHandler is a function that handles the error from May and May* functions.

func WithLogFuncHandler

func WithLogFuncHandler(logFunc func(...any)) MayHandler

WithLogFuncHandler returns a MayHandler that logs the error with the given logFunc which accepts variadic arguments.

func WithLoggerHandler

func WithLoggerHandler(l Logger) MayHandler

WithLoggerHandler returns a MayHandler that logs the error with the given logger.

func WithZapLoggerFuncHandler added in v1.4.0

func WithZapLoggerFuncHandler(logFunc func(message string, fields ...zap.Field)) MayHandler

WithZapLoggerHandler returns a MayHandler that logs the error with the given zap logger. It will automatically assert whether the passed args are zap.Field and convert the messageArgs zap.Field if it is not a string with error_field prefix.

Usage:

may := fo.NewMay()
may.Use(fo.WithZapLoggerHandler(zapLogger))
may.Invoke(os.Open("./test_file.json"), "failed to open file", zap.String("file", "test_file.json"))

type MayInvoker

type MayInvoker[T any] struct {
	// contains filtered or unexported fields
}

MayInvoker is a helper instance that enables to invoke a call to a callback function and then filters out the error from the result and only returns the value. If the error is not nil, it will be collected to mayHandlers and then handled by handlers registered by Use(...)

func NewMay

func NewMay[T any]() *MayInvoker[T]

NewMay creates a helper instance that enables to invoke a call to a callback function and then filters out the error from the result and only returns the value. If the error is not nil, it will be collected to mayHandlers and then handled by handlers registered by Use(...)

Example
errFn := func() (string, error) {
	return "", errors.New("an error")
}

may := NewMay[string]()
res1 := may.Invoke(errFn())

errNilFn := func() (string, error) {
	return "success", nil
}

res2 := may.Invoke(errNilFn())

fmt.Println(strings.Join([]string{res1, res2}, ","))
Output:
,success

func NewMay1

func NewMay1[T any]() *MayInvoker[T]

NewMay1 is an alias of NewMay.

func (MayInvoker) CollectAsError added in v1.1.0

func (h MayInvoker) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker) CollectAsErrors added in v1.1.0

func (h MayInvoker) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker) HandleErrors added in v1.1.0

func (h MayInvoker) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

Example
// Such scenario is useful when you want to handle errors in a defer statement
funcWithHandlingErrorsInDefer := func() (num int, num2 int, err error) {
	may := NewMay[int]()

	defer func() {
		// Using defer to handle errors and assign the err into named return value
		err = may.HandleErrorsWithReturn(func(errs []error) error {
			return fmt.Errorf("error occurred: %w", multierr.Combine(errs...))
		})
	}()

	funcWithErr := func() (int, error) {
		return 0, errors.New("something went wrong")
	}

	funcWithNilErr := func() (int, error) {
		return 42, nil
	}

	num = may.Invoke(funcWithErr())
	num2 = may.Invoke(funcWithNilErr())

	return num, num2, nil
}

num, num2, err := funcWithHandlingErrorsInDefer()
fmt.Println(num, num2, err)

// Such scenario is useful when you want to handle errors in a separated function
funcWithHandlingErrorsWithReformatting := func() (num int, num2 int, err error) { //nolint:unparam
	may := NewMay[int]()

	funcWithErr := func() (int, error) {
		return 0, errors.New("something went wrong")
	}

	funcWithNilErr := func() (int, error) {
		return 42, nil
	}

	num = may.Invoke(funcWithErr())
	num2 = may.Invoke(funcWithNilErr())

	may.HandleErrors(func(errs []error) {
		fmt.Println("encountered errors:", errs)
	})

	return num, num2, nil
}

num, num2, err = funcWithHandlingErrorsWithReformatting()
fmt.Println(num, num2, err)
Output:
0 42 error occurred: something went wrong
encountered errors: [something went wrong]
0 42 <nil>

func (MayInvoker) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

Example
criticalErr := errors.New("critical error")

// Such scenario is useful when you want to handle errors and then return a new one after
// reformatting, grouping, logging the errors or etc.
funcWithHandlingErrors := func() (num int, num2 int, err error) {
	may := NewMay[int]()

	funcWithErr := func() (int, error) {
		return 0, criticalErr
	}

	funcWithNilErr := func() (int, error) {
		return 42, nil
	}

	num = may.Invoke(funcWithErr())
	num2 = may.Invoke(funcWithNilErr())

	err = may.HandleErrorsWithReturn(func(errs []error) error {
		for _, e := range errs {
			if errors.Is(e, criticalErr) {
				return fmt.Errorf("critical error occurred: %w", e)
			}
		}

		return fmt.Errorf("error occurred: %w", multierr.Combine(errs...))
	})

	return num, num2, err
}

num, num2, err := funcWithHandlingErrors()
fmt.Println(num, num2, err)
Output:
0 42 critical error occurred: critical error

func (*MayInvoker[T]) Invoke

func (f *MayInvoker[T]) Invoke(t1 T, err any, messageArgs ...any) T

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker[T]) Use

func (f *MayInvoker[T]) Use(handler ...MayHandler) *MayInvoker[T]

Use registers the handlers.

Example
var outErr error

handler := func(err error, v ...any) {
	outErr = err
}

may := NewMay[string]().Use(handler)
res := may.Invoke(func() (string, error) {
	return "", errors.New("an error")
}())

fmt.Println(strings.Join([]string{res, outErr.Error()}, ","))
Output:
,an error

type MayInvoker0

type MayInvoker0 struct {
	// contains filtered or unexported fields
}

MayInvoker0 is a helper instance that behaves like MayInvoker , but it allows to invoke a callback function that returns no value.

func NewMay0

func NewMay0() *MayInvoker0

NewMay0 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns no value.

func (MayInvoker0) CollectAsError added in v1.1.0

func (h MayInvoker0) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker0) CollectAsErrors added in v1.1.0

func (h MayInvoker0) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker0) HandleErrors added in v1.1.0

func (h MayInvoker0) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker0) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker0) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker0) Invoke

func (f *MayInvoker0) Invoke(anyErr any, messageArgs ...any)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker0) Use

func (f *MayInvoker0) Use(handler ...MayHandler) *MayInvoker0

Use registers the handlers.

type MayInvoker2

type MayInvoker2[T1 any, T2 any] struct {
	// contains filtered or unexported fields
}

MayInvoker2 is a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 2 values.

func NewMay2

func NewMay2[T1 any, T2 any]() *MayInvoker2[T1, T2]

NewMay2 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 2 values.

func (MayInvoker2) CollectAsError added in v1.1.0

func (h MayInvoker2) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker2) CollectAsErrors added in v1.1.0

func (h MayInvoker2) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker2) HandleErrors added in v1.1.0

func (h MayInvoker2) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker2) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker2) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker2[T1, T2]) Invoke

func (f *MayInvoker2[T1, T2]) Invoke(t1 T1, t2 T2, err any, messageArgs ...any) (T1, T2)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker2[T1, T2]) Use

func (f *MayInvoker2[T1, T2]) Use(handler ...MayHandler) *MayInvoker2[T1, T2]

Use registers the handlers.

type MayInvoker3

type MayInvoker3[T1 any, T2 any, T3 any] struct {
	// contains filtered or unexported fields
}

MayInvoker3 is a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 3 values.

func NewMay3

func NewMay3[T1 any, T2 any, T3 any]() *MayInvoker3[T1, T2, T3]

NewMay3 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 3 values.

func (MayInvoker3) CollectAsError added in v1.1.0

func (h MayInvoker3) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker3) CollectAsErrors added in v1.1.0

func (h MayInvoker3) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker3) HandleErrors added in v1.1.0

func (h MayInvoker3) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker3) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker3) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker3[T1, T2, T3]) Invoke

func (f *MayInvoker3[T1, T2, T3]) Invoke(t1 T1, t2 T2, t3 T3, err any, messageArgs ...any) (T1, T2, T3)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker3[T1, T2, T3]) Use

func (f *MayInvoker3[T1, T2, T3]) Use(handler ...MayHandler) *MayInvoker3[T1, T2, T3]

Use registers the handlers.

type MayInvoker4

type MayInvoker4[T1 any, T2 any, T3 any, T4 any] struct {
	// contains filtered or unexported fields
}

MayInvoker4 is a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 4 values.

func NewMay4

func NewMay4[T1 any, T2 any, T3 any, T4 any]() *MayInvoker4[T1, T2, T3, T4]

NewMay4 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 4 values.

func (MayInvoker4) CollectAsError added in v1.1.0

func (h MayInvoker4) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker4) CollectAsErrors added in v1.1.0

func (h MayInvoker4) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker4) HandleErrors added in v1.1.0

func (h MayInvoker4) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker4) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker4) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker4[T1, T2, T3, T4]) Invoke

func (f *MayInvoker4[T1, T2, T3, T4]) Invoke(t1 T1, t2 T2, t3 T3, t4 T4, err any, messageArgs ...any) (T1, T2, T3, T4)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker4[T1, T2, T3, T4]) Use

func (f *MayInvoker4[T1, T2, T3, T4]) Use(handler ...MayHandler) *MayInvoker4[T1, T2, T3, T4]

Use registers the handlers.

type MayInvoker5

type MayInvoker5[T1 any, T2 any, T3 any, T4 any, T5 any] struct {
	// contains filtered or unexported fields
}

MayInvoker5 is a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 5 values.

func NewMay5

func NewMay5[T1 any, T2 any, T3 any, T4 any, T5 any]() *MayInvoker5[T1, T2, T3, T4, T5]

NewMay5 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 5 values.

func (MayInvoker5) CollectAsError added in v1.1.0

func (h MayInvoker5) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker5) CollectAsErrors added in v1.1.0

func (h MayInvoker5) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker5) HandleErrors added in v1.1.0

func (h MayInvoker5) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker5) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker5) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker5[T1, T2, T3, T4, T5]) Invoke

func (f *MayInvoker5[T1, T2, T3, T4, T5]) Invoke(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, err any, messageArgs ...any) (T1, T2, T3, T4, T5)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker5[T1, T2, T3, T4, T5]) Use

func (f *MayInvoker5[T1, T2, T3, T4, T5]) Use(handler ...MayHandler) *MayInvoker5[T1, T2, T3, T4, T5]

Use registers the handlers.

type MayInvoker6

type MayInvoker6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any] struct {
	// contains filtered or unexported fields
}

MayInvoker6 is a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 6 values.

func NewMay6

func NewMay6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any]() *MayInvoker6[T1, T2, T3, T4, T5, T6]

NewMay6 creates a helper instance behaves like MayInvoker, but it allows to invoke a callback function that returns 6 values.

func (MayInvoker6) CollectAsError added in v1.1.0

func (h MayInvoker6) CollectAsError() error

CollectAsError collects error from the invoked result from MayInvoker for post error handling.

The error can be extracted with

multierr.Errors().

func (MayInvoker6) CollectAsErrors added in v1.1.0

func (h MayInvoker6) CollectAsErrors() []error

CollectAsErrors collects errors from the invoked result from MayInvoker for post error handling.

The errors can be combined with

multierr.Combine().

func (MayInvoker6) HandleErrors added in v1.1.0

func (h MayInvoker6) HandleErrors(handler func(errs []error))

HandleErrors executes the handler with the collected error from MayInvoker.

func (MayInvoker6) HandleErrorsWithReturn added in v1.1.0

func (h MayInvoker6) HandleErrorsWithReturn(handler func(errs []error) error) error

HandleErrorsWithReturn executes the handler with the collected error from MayInvoker, and returns the error that handled by the handler.

func (*MayInvoker6[T1, T2, T3, T4, T5, T6]) Invoke

func (f *MayInvoker6[T1, T2, T3, T4, T5, T6]) Invoke(t1 T1, t2 T2, t3 T3, t4 T4, t5 T5, t6 T6, err any, messageArgs ...any) (T1, T2, T3, T4, T5, T6)

Invoke invokes the callback function and filters out the error from the result and only returns the value. If the error is not nil, it will be collected and handled by handlers registered by Use(...)

func (*MayInvoker6[T1, T2, T3, T4, T5, T6]) Use

func (f *MayInvoker6[T1, T2, T3, T4, T5, T6]) Use(handler ...MayHandler) *MayInvoker6[T1, T2, T3, T4, T5, T6]

Use registers the handlers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL