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} } func WrapResultOutputFunc[I, O any](f func(I) (O, error)) func(I) Result[O] { return func(i I) Result[O] { return ResultOf(f(i)) } } func WrapResultFunc[I, O any](f func(I) (O, error)) func(Result[I]) Result[O] { resFunc := WrapResultOutputFunc(f) 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 } return *r.value, r.err } func (r Result[T]) GetUnsafe() T { if r.err != nil { panic(r.err) } return *r.value } func (r Result[T]) Err() error { return r.err } func FilterSuccess[T any](source <-chan Result[T]) <-chan T { succeeded := Filter(source, Result[T].Success) return MapSuccessive(succeeded, func(r Result[T]) T { v, _ := r.Get() return v }) } func FilterFail[T any](source <-chan Result[T]) <-chan T { failed := Filter(source, Result[T].Fail) 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 { if r.Fail() { fail <- r.Err() continue } succ <- r.GetUnsafe() } }() return succ, fail }