channel/result.go

103 lines
1.8 KiB
Go
Raw Normal View History

2023-03-25 11:12:36 +01:00
package channel
type Result[T any] struct {
value *T
err error
}
func ResultOf[T any](value T, err error) Result[T] {
if err != nil {
return Result[T]{value: nil, err: err}
}
return Result[T]{value: &value, err: nil}
}
2024-04-04 19:13:43 +02:00
func WrapResultOutputFunc[I, O any](f func(I) (O, error)) func(I) Result[O] {
2023-03-25 11:12:36 +01:00
return func(i I) Result[O] { return ResultOf(f(i)) }
}
2024-04-04 19:13:43 +02:00
func WrapResultFunc[I, O any](f func(I) (O, error)) func(Result[I]) Result[O] {
resFunc := WrapResultOutputFunc(f)
2023-03-25 11:12:36 +01:00
nilValue := *new(O)
return func(r Result[I]) Result[O] {
v, err := r.Get()
if err != nil {
return ResultOf(nilValue, err)
}
return resFunc(v)
}
}
func (r Result[T]) Success() bool {
return r.err == nil
}
func (r Result[T]) Fail() bool {
return !r.Success()
}
func (r Result[T]) GetOrDefault(defaultValue T) T {
if r.Fail() {
return defaultValue
}
return *r.value
}
func (r Result[T]) Get() (T, error) {
if r.err != nil {
return *new(T), r.err
}
2023-03-25 11:12:36 +01:00
return *r.value, r.err
}
2023-03-25 11:37:08 +01:00
func (r Result[T]) GetUnsafe() T {
2023-03-25 11:49:59 +01:00
if r.err != nil {
panic(r.err)
}
return *r.value
}
func (r Result[T]) Err() error {
return r.err
}
2023-03-25 11:37:08 +01:00
func FilterSuccess[T any](source <-chan Result[T]) <-chan T {
2024-04-04 19:11:33 +02:00
succeeded := Filter(source, Result[T].Success)
2023-03-25 11:37:08 +01:00
return MapSuccessive(succeeded, func(r Result[T]) T {
v, _ := r.Get()
return v
})
}
2023-03-25 11:45:55 +01:00
func FilterFail[T any](source <-chan Result[T]) <-chan T {
2024-04-04 19:11:33 +02:00
failed := Filter(source, Result[T].Fail)
2023-03-25 11:45:55 +01:00
return MapSuccessive(failed, func(r Result[T]) T {
v, _ := r.Get()
return v
})
}
func FilterResults[T any](source <-chan Result[T]) (succeeded <-chan T, failed <-chan error) {
succ := make(chan T, cap(source))
fail := make(chan error, cap(source))
go func() {
defer close(succ)
defer close(fail)
for r := range source {
2023-03-25 11:49:59 +01:00
if r.Fail() {
fail <- r.Err()
continue
2023-03-25 11:45:55 +01:00
}
2024-04-04 19:11:33 +02:00
succ <- r.GetUnsafe()
2023-03-25 11:45:55 +01:00
}
}()
return succ, fail
}