Skip to content

Commit

Permalink
doc: adding examples
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed Oct 6, 2022
1 parent 835fc01 commit c6b8b1e
Show file tree
Hide file tree
Showing 8 changed files with 832 additions and 4 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

@samber: I sometimes forget to update this file. Ping me on [Twitter](https://twitter.com/samuelberthe) or open an issue in case of error. We need to keep a clear changelog for easier lib upgrade.

## 1.30.1 (2022-10-06)

Fix:

- lo.Try1: remove generic type
- lo.Validate: format error properly

## 1.30.0 (2022-10-04)

Adding:
Expand Down
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1137,14 +1137,16 @@ sub := len("hellô")
Creates a tuple from a list of values.

```go
tuple1 := lo.T2[string, int]("x", 1)
tuple1 := lo.T2("x", 1)
// Tuple2[string, int]{A: "x", B: 1}

func example() (string, int) { return "y", 2 }
tuple2 := lo.T2[string, int](example())
tuple2 := lo.T2(example())
// Tuple2[string, int]{A: "y", B: 2}
```

[[play](https://go.dev/play/p/IllL3ZO4BQm)]

### Unpack2 -> Unpack9

Returns values contained in tuple.
Expand All @@ -1154,6 +1156,8 @@ r1, r2 := lo.Unpack2[string, int](lo.Tuple2[string, int]{"a", 1})
// "a", 1
```

[[play](https://go.dev/play/p/xVP_k0kJ96W)]

### Zip2 -> Zip9

Zip creates a slice of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.
Expand All @@ -1165,6 +1169,8 @@ tuples := lo.Zip2[string, int]([]string{"a", "b"}, []int{1, 2})
// []Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B: 2}}
```

[[play](https://go.dev/play/p/jujaA6GaJTp)]

### Unzip2 -> Unzip9

Unzip accepts an array of grouped elements and creates an array regrouping the elements to their pre-zip configuration.
Expand All @@ -1175,6 +1181,8 @@ a, b := lo.Unzip2[string, int]([]Tuple2[string, int]{{A: "a", B: 1}, {A: "b", B:
// []int{1, 2}
```

[[play](https://go.dev/play/p/ciHugugvaAW)]

### ChannelDispatcher

Distributes messages from input channels into N child channels. Close events are propagated to children.
Expand Down Expand Up @@ -1982,6 +1990,8 @@ iter, err := lo.Attempt(0, func(i int) error {

For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).

[[play](https://go.dev/play/p/3ggJZ2ZKcMj)]

### AttemptWithDelay

Invokes a function N times until it returns valid output, with a pause between each call. Returning either the caught error or nil.
Expand All @@ -2003,6 +2013,8 @@ iter, duration, err := lo.AttemptWithDelay(5, 2*time.Second, func(i int, duratio

For more advanced retry strategies (delay, exponential backoff...), please take a look on [cenkalti/backoff](https://github.com/cenkalti/backoff).

[[play](https://go.dev/play/p/tVs6CygC7m1)]

### Debounce

`NewDebounce` creates a debounced instance that delays invoking functions given until after wait milliseconds have elapsed, until `cancel` is called.
Expand All @@ -2021,6 +2033,8 @@ time.Sleep(1 * time.Second)
cancel()
```

[[play](https://go.dev/play/p/mz32VMK2nqe)]

### Synchronize

Wraps the underlying callback in a mutex. It receives an optional mutex.
Expand Down Expand Up @@ -2094,6 +2108,8 @@ val := lo.Validate(len(slice) == 0, "Slice should be empty but contains %v", sli
// nil
```

[[play](https://go.dev/play/p/vPyh51XpCBt)]

### Must

Wraps a function call to panics if second argument is `error` or `false`, returns the value otherwise.
Expand All @@ -2106,6 +2122,8 @@ val := lo.Must(time.Parse("2006-01-02", "bad-value"))
// panics
```

[[play](https://go.dev/play/p/TMoWrRp3DyC)]

### Must{0->6}

Must\* has the same behavior than Must, but returns multiple values.
Expand Down Expand Up @@ -2152,6 +2170,8 @@ lo.Must0(lo.Contains[int](list, item), "'%s' must always contain '%s'", list, it
...
```

[[play](https://go.dev/play/p/TMoWrRp3DyC)]

### Try

Calls the function and return false in case of error and on panic.
Expand All @@ -2174,6 +2194,8 @@ ok := lo.Try(func() error {
// false
```

[[play](https://go.dev/play/p/mTyyWUvn9u4)]

### Try{0->6}

The same behavior than `Try`, but callback returns 2 variables.
Expand All @@ -2186,6 +2208,8 @@ ok := lo.Try2(func() (string, error) {
// false
```

[[play](https://go.dev/play/p/mTyyWUvn9u4)]

### TryOr

Calls the function and return a default value in case of error and on panic.
Expand All @@ -2211,6 +2235,8 @@ ok := lo.TryOr(func() error {
// false
```

[[play](https://go.dev/play/p/B4F7Wg2Zh9X)]

### TryOr{0->6}

The same behavior than `TryOr`, but callback returns 2 variables.
Expand All @@ -2225,6 +2251,8 @@ str, nbr, ok := lo.TryOr2(func() (string, int, error) {
// false
```

[[play](https://go.dev/play/p/B4F7Wg2Zh9X)]

### TryWithErrorValue

The same behavior than `Try`, but also returns value passed to panic.
Expand All @@ -2237,6 +2265,8 @@ err, ok := lo.TryWithErrorValue(func() error {
// "error", false
```

[[play](https://go.dev/play/p/Kc7afQIT2Fs)]

### TryCatch

The same behavior than `Try`, but calls the catch function in case of error.
Expand All @@ -2254,6 +2284,8 @@ ok := lo.TryCatch(func() error {
// caught == true
```

[[play](https://go.dev/play/p/PnOON-EqBiU)]

### TryCatchWithErrorValue

The same behavior than `TryWithErrorValue`, but calls the catch function in case of error.
Expand All @@ -2271,6 +2303,8 @@ ok := lo.TryCatchWithErrorValue(func() error {
// caught == true
```

[[play](https://go.dev/play/p/8Pc9gwX_GZO)]

### ErrorsAs

A shortcut for:
Expand All @@ -2294,6 +2328,8 @@ if rateLimitErr, ok := lo.ErrorsAs[*RateLimitError](err); ok {
}
```

[[play](https://go.dev/play/p/8wk5rH8UfrE)]

## 🛩 Benchmark

We executed a simple benchmark with the a dead-simple `lo.Map` loop:
Expand Down
31 changes: 29 additions & 2 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
)

// Validate is a helper that creates an error when a condition is not met.
// Play: https://go.dev/play/p/vPyh51XpCBt
func Validate(ok bool, format string, args ...any) error {
if !ok {
return errors.New(fmt.Sprint(format, args))
return errors.New(fmt.Sprintf(format, args...))
}
return nil
}
Expand Down Expand Up @@ -59,46 +60,54 @@ func must(err any, messageArgs ...interface{}) {

// Must is a helper that wraps a call to a function returning a value and an error
// and panics if err is error or false.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must[T any](val T, err any, messageArgs ...interface{}) T {
must(err, messageArgs...)
return val
}

// Must0 has the same behavior than Must, but callback returns no variable.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must0(err any, messageArgs ...interface{}) {
must(err, messageArgs...)
}

// Must1 is an alias to Must
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must1[T any](val T, err any, messageArgs ...interface{}) T {
return Must(val, err, messageArgs...)
}

// Must2 has the same behavior than Must, but callback returns 2 variables.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must2[T1 any, T2 any](val1 T1, val2 T2, err any, messageArgs ...interface{}) (T1, T2) {
must(err, messageArgs...)
return val1, val2
}

// Must3 has the same behavior than Must, but callback returns 3 variables.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err any, messageArgs ...interface{}) (T1, T2, T3) {
must(err, messageArgs...)
return val1, val2, val3
}

// Must4 has the same behavior than Must, but callback returns 4 variables.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any, messageArgs ...interface{}) (T1, T2, T3, T4) {
must(err, messageArgs...)
return val1, val2, val3, val4
}

// Must5 has the same behavior than Must, but callback returns 5 variables.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5) {
must(err, messageArgs...)
return val1, val2, val3, val4, val5
}

// Must6 has the same behavior than Must, but callback returns 6 variables.
// Play: https://go.dev/play/p/TMoWrRp3DyC
func Must6[T1 any, T2 any, T3 any, T4 any, T5 any, T6 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, val6 T6, err any, messageArgs ...interface{}) (T1, T2, T3, T4, T5, T6) {
must(err, messageArgs...)
return val1, val2, val3, val4, val5, val6
Expand All @@ -123,6 +132,7 @@ func Try(callback func() error) (ok bool) {
}

// Try0 has the same behavior than Try, but callback returns no variable.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try0(callback func()) bool {
return Try(func() error {
callback()
Expand All @@ -131,11 +141,13 @@ func Try0(callback func()) bool {
}

// Try1 is an alias to Try.
func Try1[T any](callback func() error) bool {
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try1(callback func() error) bool {
return Try(callback)
}

// Try2 has the same behavior than Try, but callback returns 2 variables.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try2[T any](callback func() (T, error)) bool {
return Try(func() error {
_, err := callback()
Expand All @@ -144,6 +156,7 @@ func Try2[T any](callback func() (T, error)) bool {
}

// Try3 has the same behavior than Try, but callback returns 3 variables.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try3[T, R any](callback func() (T, R, error)) bool {
return Try(func() error {
_, _, err := callback()
Expand All @@ -152,6 +165,7 @@ func Try3[T, R any](callback func() (T, R, error)) bool {
}

// Try4 has the same behavior than Try, but callback returns 4 variables.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try4[T, R, S any](callback func() (T, R, S, error)) bool {
return Try(func() error {
_, _, _, err := callback()
Expand All @@ -160,6 +174,7 @@ func Try4[T, R, S any](callback func() (T, R, S, error)) bool {
}

// Try5 has the same behavior than Try, but callback returns 5 variables.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try5[T, R, S, Q any](callback func() (T, R, S, Q, error)) bool {
return Try(func() error {
_, _, _, _, err := callback()
Expand All @@ -168,6 +183,7 @@ func Try5[T, R, S, Q any](callback func() (T, R, S, Q, error)) bool {
}

// Try6 has the same behavior than Try, but callback returns 6 variables.
// Play: https://go.dev/play/p/mTyyWUvn9u4
func Try6[T, R, S, Q, U any](callback func() (T, R, S, Q, U, error)) bool {
return Try(func() error {
_, _, _, _, _, err := callback()
Expand All @@ -176,11 +192,13 @@ func Try6[T, R, S, Q, U any](callback func() (T, R, S, Q, U, error)) bool {
}

// TryOr has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr[A any](callback func() (A, error), fallbackA A) (A, bool) {
return TryOr1(callback, fallbackA)
}

// TryOr1 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) {
ok := false

Expand All @@ -196,6 +214,7 @@ func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) {
}

// TryOr2 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr2[A any, B any](callback func() (A, B, error), fallbackA A, fallbackB B) (A, B, bool) {
ok := false

Expand All @@ -212,6 +231,7 @@ func TryOr2[A any, B any](callback func() (A, B, error), fallbackA A, fallbackB
}

// TryOr3 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr3[A any, B any, C any](callback func() (A, B, C, error), fallbackA A, fallbackB B, fallbackC C) (A, B, C, bool) {
ok := false

Expand All @@ -229,6 +249,7 @@ func TryOr3[A any, B any, C any](callback func() (A, B, C, error), fallbackA A,
}

// TryOr4 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr4[A any, B any, C any, D any](callback func() (A, B, C, D, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D) (A, B, C, D, bool) {
ok := false

Expand All @@ -247,6 +268,7 @@ func TryOr4[A any, B any, C any, D any](callback func() (A, B, C, D, error), fal
}

// TryOr5 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr5[A any, B any, C any, D any, E any](callback func() (A, B, C, D, E, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E) (A, B, C, D, E, bool) {
ok := false

Expand All @@ -266,6 +288,7 @@ func TryOr5[A any, B any, C any, D any, E any](callback func() (A, B, C, D, E, e
}

// TryOr6 has the same behavior than Must, but returns a default value in case of error.
// Play: https://go.dev/play/p/B4F7Wg2Zh9X
func TryOr6[A any, B any, C any, D any, E any, F any](callback func() (A, B, C, D, E, F, error), fallbackA A, fallbackB B, fallbackC C, fallbackD D, fallbackE E, fallbackF F) (A, B, C, D, E, F, bool) {
ok := false

Expand All @@ -286,6 +309,7 @@ func TryOr6[A any, B any, C any, D any, E any, F any](callback func() (A, B, C,
}

// TryWithErrorValue has the same behavior than Try, but also returns value passed to panic.
// Play: https://go.dev/play/p/Kc7afQIT2Fs
func TryWithErrorValue(callback func() error) (errorValue any, ok bool) {
ok = true

Expand All @@ -306,20 +330,23 @@ func TryWithErrorValue(callback func() error) (errorValue any, ok bool) {
}

// TryCatch has the same behavior than Try, but calls the catch function in case of error.
// Play: https://go.dev/play/p/PnOON-EqBiU
func TryCatch(callback func() error, catch func()) {
if !Try(callback) {
catch()
}
}

// TryCatchWithErrorValue has the same behavior than TryWithErrorValue, but calls the catch function in case of error.
// Play: https://go.dev/play/p/8Pc9gwX_GZO
func TryCatchWithErrorValue(callback func() error, catch func(any)) {
if err, ok := TryWithErrorValue(callback); !ok {
catch(err)
}
}

// ErrorsAs is a shortcut for errors.As(err, &&T).
// Play: https://go.dev/play/p/8wk5rH8UfrE
func ErrorsAs[T error](err error) (T, bool) {
var t T
ok := errors.As(err, &t)
Expand Down
Loading

0 comments on commit c6b8b1e

Please sign in to comment.