Skip to content

Commit

Permalink
Merge pull request #103 from wirekang/feat-must-any
Browse files Browse the repository at this point in the history
Fix Must to receives 'err any'
  • Loading branch information
samber committed Apr 22, 2022
2 parents 1bec3a3 + a894d7c commit b0ae2e4
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 46 deletions.
29 changes: 18 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ ch := lo.Async[error](func() Tuple2[int, error] {

### Must

Wraps a function call to return the given value if the error is nil, panics otherwise.
Wraps a function call to panics if second argument is `error` or `false`, returns the value otherwise.

```go
val := Must(time.Parse("2006-01-02", "2022-01-15"))
Expand All @@ -1263,9 +1263,7 @@ val := Must(time.Parse("2006-01-02", "bad-value"))
```

### Must{0->6}

Wraps a function call to return values if the error is nil, panics otherwise.

Must* has the same behavior than Must, but returns multiple values.
```go
func example0() (error)
func example1() (int, error)
Expand All @@ -1275,13 +1273,22 @@ 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)

Must0(example0)
val1 := Must1(example1) // alias to Must
val1, val2 := Must2(example2)
val1, val2, val3 := Must3(example3)
val1, val2, val3, val4 := Must4(example4)
val1, val2, val3, val4, val5 := Must5(example5)
val1, val2, val3, val4, val5, val6 := Must6(example6)
Must0(example0())
val1 := Must1(example1()) // alias to Must
val1, val2 := Must2(example2())
val1, val2, val3 := Must3(example3())
val1, val2, val3, val4 := Must4(example4())
val1, val2, val3, val4, val5 := Must5(example5())
val1, val2, val3, val4, val5, val6 := Must6(example6())
```

You can wrap functions like `func (...) (..., ok bool)`.
```go
// math.Signbit(float64) bool
Must0(math.Signbit(v))

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

## Try
Expand Down
63 changes: 28 additions & 35 deletions errors.go
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
package lo

// Must is a helper that wraps a call to a function returning a value and an error
// and panics if the error is non-nil.
func Must[T any](val T, err error) T {
if err != nil {
panic(err)
// must panics if err is error or false.
func must(err any) {
b, isBool := err.(bool)
if isBool && !b {
panic("not ok")
}

e, isError := err.(error)
if isError {
panic(e)
}
}

// 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.
func Must[T any](val T, err any) T {
must(err)
return val
}

// Must0 has the same behavior than Must, but callback returns no variable.
func Must0(err error) {
if err != nil {
panic(err)
}
func Must0(err any) {
must(err)
}

// Must1 is an alias to Must
func Must1[T any](val T, err error) T {
func Must1[T any](val T, err any) T {
return Must(val, err)
}

// Must2 has the same behavior than Must, but callback returns 2 variables.
func Must2[T1 any, T2 any](val1 T1, val2 T2, err error) (T1, T2) {
if err != nil {
panic(err)
}

func Must2[T1 any, T2 any](val1 T1, val2 T2, err any) (T1, T2) {
must(err)
return val1, val2
}

// Must3 has the same behavior than Must, but callback returns 3 variables.
func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err error) (T1, T2, T3) {
if err != nil {
panic(err)
}

func Must3[T1 any, T2 any, T3 any](val1 T1, val2 T2, val3 T3, err any) (T1, T2, T3) {
must(err)
return val1, val2, val3
}

// Must4 has the same behavior than Must, but callback returns 4 variables.
func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err error) (T1, T2, T3, T4) {
if err != nil {
panic(err)
}

func Must4[T1 any, T2 any, T3 any, T4 any](val1 T1, val2 T2, val3 T3, val4 T4, err any) (T1, T2, T3, T4) {
must(err)
return val1, val2, val3, val4
}

// Must5 has the same behavior than Must, but callback returns 5 variables.
func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err error) (T1, T2, T3, T4, T5) {
if err != nil {
panic(err)
}

func Must5[T1 any, T2 any, T3 any, T4 any, T5 any](val1 T1, val2 T2, val3 T3, val4 T4, val5 T5, err any) (T1, T2, T3, T4, T5) {
must(err)
return val1, val2, val3, val4, val5
}

// Must6 has the same behavior than Must, but callback returns 6 variables.
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 error) (T1, T2, T3, T4, T5, T6) {
if err != nil {
panic(err)
}

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) (T1, T2, T3, T4, T5, T6) {
must(err)
return val1, val2, val3, val4, val5, val6
}

Expand Down
77 changes: 77 additions & 0 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ func TestMust(t *testing.T) {
is.Panics(func() {
Must("", errors.New("something went wrong"))
})

is.Equal(1, Must(1, true))
is.Panics(func() {
Must(1, false)
})
}

func TestMustX(t *testing.T) {
Expand Down Expand Up @@ -108,6 +113,78 @@ func TestMustX(t *testing.T) {
Must6(1, 2, 3, 4, 5, 6, nil)
})
}

{
is.Panics(func() {
Must0(false)
})
is.NotPanics(func() {
Must0(true)
})
}

{
val1 := Must1(1, true)
is.Equal(1, val1)
is.Panics(func() {
Must1(1, false)
})
}

{
val1, val2 := Must2(1, 2, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Panics(func() {
Must2(1, 2, false)
})
}

{
val1, val2, val3 := Must3(1, 2, 3, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Panics(func() {
Must3(1, 2, 3, false)
})
}

{
val1, val2, val3, val4 := Must4(1, 2, 3, 4, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Panics(func() {
Must4(1, 2, 3, 4, false)
})
}

{
val1, val2, val3, val4, val5 := Must5(1, 2, 3, 4, 5, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.Panics(func() {
Must5(1, 2, 3, 4, 5, false)
})
}

{
val1, val2, val3, val4, val5, val6 := Must6(1, 2, 3, 4, 5, 6, true)
is.Equal(1, val1)
is.Equal(2, val2)
is.Equal(3, val3)
is.Equal(4, val4)
is.Equal(5, val5)
is.Equal(6, val6)
is.Panics(func() {
Must6(1, 2, 3, 4, 5, 6, false)
})
}
}

func TestTry(t *testing.T) {
Expand Down

0 comments on commit b0ae2e4

Please sign in to comment.