-
-
Notifications
You must be signed in to change notification settings - Fork 109
Expand file tree
/
Copy pathresult.go
More file actions
139 lines (114 loc) · 3.02 KB
/
result.go
File metadata and controls
139 lines (114 loc) · 3.02 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package mo
// Ok builds a Result when value is valid.
func Ok[T any](value T) Result[T] {
return Result[T]{
value: value,
isErr: false,
}
}
// Err builds a Result when value is invalid.
func Err[T any](err error) Result[T] {
return Result[T]{
err: err,
isErr: true,
}
}
// TupleToResult convert a pair of T and error into a Result.
func TupleToResult[T any](value T, err error) Result[T] {
if err != nil {
return Err[T](err)
}
return Ok(value)
}
// Try returns either a Ok or Err object.
func Try[T any](f func() (T, error)) Result[T] {
return TupleToResult(f())
}
// Result respresent a result of an action having one
// of the following output: success or failure.
// An instance of Result is an instance of either Ok or Err.
// It could be compared to `Either[error, T]`.
type Result[T any] struct {
isErr bool
value T
err error
}
// IsOk returns true when value is valid.
func (r Result[T]) IsOk() bool {
return !r.isErr
}
// IsError returns true when value is invalid.
func (r Result[T]) IsError() bool {
return r.isErr
}
// Error returns error when value is invalid or nil.
func (r Result[T]) Error() error {
return r.err
}
// MustGet returns value and error.
func (r Result[T]) Get() (T, error) {
if r.isErr {
return empty[T](), r.err
}
return r.value, nil
}
// MustGet returns value when Result is valid or panics.
func (r Result[T]) MustGet() T {
if r.isErr {
panic(r.err)
}
return r.value
}
// OrElse returns value when Result is valid or default value.
func (r Result[T]) OrElse(fallback T) T {
if r.isErr {
return fallback
}
return r.value
}
// OrEmpty returns value when Result is valid or empty value.
func (r Result[T]) OrEmpty() T {
return r.value
}
// ToEither transforms a Result into an Either type.
func (r Result[T]) ToEither() Either[error, T] {
if r.isErr {
return Left[error, T](r.err)
}
return Right[error, T](r.value)
}
// ForEach executes the given side-effecting function if Result is valid.
func (r Result[T]) ForEach(mapper func(value T)) {
if !r.isErr {
mapper(r.value)
}
}
// Match executes the first function if Result is valid and second function if invalid.
// It returns a new Result.
func (r Result[T]) Match(onSuccess func(value T) (T, error), onError func(err error) (T, error)) Result[T] {
if r.isErr {
return TupleToResult(onError(r.err))
}
return TupleToResult(onSuccess(r.value))
}
// Map executes the mapper function if Result is valid. It returns a new Result.
func (r Result[T]) Map(mapper func(value T) (T, error)) Result[T] {
if !r.isErr {
return TupleToResult(mapper(r.value))
}
return Err[T](r.err)
}
// MapErr executes the mapper function if Result is invalid. It returns a new Result.
func (r Result[T]) MapErr(mapper func(error) (T, error)) Result[T] {
if r.isErr {
return TupleToResult(mapper(r.err))
}
return Ok(r.value)
}
// FlatMap executes the mapper function if Result is valid. It returns a new Result.
func (r Result[T]) FlatMap(mapper func(value T) Result[T]) Result[T] {
if !r.isErr {
return mapper(r.value)
}
return Err[T](r.err)
}