Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding TryOr and TryOrX #229

Merged
merged 2 commits into from Oct 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,8 @@
Adding:

- lo.ErrorAs
- lo.TryOr
- lo.TryOrX

## 1.28.0 (2022-09-05)

Expand Down
42 changes: 42 additions & 0 deletions README.md
Expand Up @@ -209,6 +209,9 @@ Error handling:

- [Must](#must)
- [Try](#try)
- [Try1 -> Try6](#try0-6)
- [TryOr](#tryor)
- [TryOr1 -> TryOr6](#tryor0-6)
- [TryCatch](#trycatch)
- [TryWithErrorValue](#trywitherrorvalue)
- [TryCatchWithErrorValue](#trycatchwitherrorvalue)
Expand Down Expand Up @@ -2026,6 +2029,45 @@ ok := lo.Try2(func() (string, error) {
// false
```

### TryOr

Calls the function and return a default value in case of error and on panic.

```go
str, ok := lo.TryOr(func() (string, error) {
panic("error")
return "hello", nil
}, "world")
// world
// false

ok := lo.TryOr(func() error {
return "hello", nil
}, "world")
// hello
// true

ok := lo.TryOr(func() error {
return "hello", fmt.Errorf("error")
}, "world")
// world
// false
```

### TryOr{0->6}

The same behavior than `TryOr`, but callback returns 2 variables.

```go
str, nbr, ok := lo.TryOr2(func() (string, int, error) {
panic("error")
return "hello", 42, nil
}, "world", 21)
// world
// 21
// false
```

### TryWithErrorValue

The same behavior than `Try`, but also returns value passed to panic.
Expand Down
110 changes: 110 additions & 0 deletions errors.go
Expand Up @@ -167,6 +167,116 @@ 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.
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.
func TryOr1[A any](callback func() (A, error), fallbackA A) (A, bool) {
ok := false

Try0(func() {
a, err := callback()
if err == nil {
fallbackA = a
ok = true
}
})

return fallbackA, ok
}

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

Try0(func() {
a, b, err := callback()
if err == nil {
fallbackA = a
fallbackB = b
ok = true
}
})

return fallbackA, fallbackB, ok
}

// TryOr3 has the same behavior than Must, but returns a default value in case of error.
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

Try0(func() {
a, b, c, err := callback()
if err == nil {
fallbackA = a
fallbackB = b
fallbackC = c
ok = true
}
})

return fallbackA, fallbackB, fallbackC, ok
}

// TryOr4 has the same behavior than Must, but returns a default value in case of error.
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

Try0(func() {
a, b, c, d, err := callback()
if err == nil {
fallbackA = a
fallbackB = b
fallbackC = c
fallbackD = d
ok = true
}
})

return fallbackA, fallbackB, fallbackC, fallbackD, ok
}

// TryOr5 has the same behavior than Must, but returns a default value in case of error.
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

Try0(func() {
a, b, c, d, e, err := callback()
if err == nil {
fallbackA = a
fallbackB = b
fallbackC = c
fallbackD = d
fallbackE = e
ok = true
}
})

return fallbackA, fallbackB, fallbackC, fallbackD, fallbackE, ok
}

// TryOr6 has the same behavior than Must, but returns a default value in case of error.
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

Try0(func() {
a, b, c, d, e, f, err := callback()
if err == nil {
fallbackA = a
fallbackB = b
fallbackC = c
fallbackD = d
fallbackE = e
fallbackF = f
ok = true
}
})

return fallbackA, fallbackB, fallbackC, fallbackD, fallbackE, fallbackF, ok
}

// TryWithErrorValue has the same behavior than Try, but also returns value passed to panic.
func TryWithErrorValue(callback func() error) (errorValue any, ok bool) {
ok = true
Expand Down