-
Notifications
You must be signed in to change notification settings - Fork 0
/
goext.go
67 lines (59 loc) · 1.51 KB
/
goext.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package goext
import (
"errors"
"fmt"
)
// ReadAll reads all values from the channel at once.
func ReadAll[T any](ch <-chan T) []T {
values := []T{}
for val := range ch {
values = append(values, val)
}
return values
}
// Ok asserts a typical Golang function call which returns a result and an error is successful and
// returns the result, it panics if the return error is not nil. This function should be composite
// with the `goext.Try()` function, allowing the program to bubble the error and catch it from
// outside.
//
// Example:
//
// _, err := goext.Try(func () int {
// res1 := goext.Ok(someCall())
// res2 := goext.Ok(anotherCall())
// return 0
// })
func Ok[R any](res R, err error) R {
if err == nil {
return res
} else {
panic(err)
}
}
// Try runs a function in a safe context where if it or what's inside it panics, the panic reason
// can be caught and returned as a normal error.
func Try[R any](fn func() R) (res R, err error) {
defer func() {
if re := recover(); re != nil {
if _err, ok := re.(error); ok {
err = _err
} else if str, ok := re.(string); ok {
err = errors.New(str)
} else {
err = errors.New(fmt.Sprint(re))
}
}
}()
return fn(), nil
}
// Wrap returns a new function that wraps the `goext.Try()`, rendering the new function already
// catchable.
//
// Deprecated: this function is not good.
func Wrap[R any](fn func(args ...any) R) func(args ...any) (R, error) {
return func(args ...any) (R, error) {
return Try(func() R {
return fn(args...)
})
}
}