fo

package module
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2024 License: MIT Imports: 7 Imported by: 2

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.

```go
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.

πŸ“ 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.

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