From 3fe5550a3bb1fbca159f4e4e1f4d766f2757ad2e Mon Sep 17 00:00:00 2001 From: Dima Kossovich Date: Mon, 16 Oct 2023 01:31:55 +0300 Subject: [PATCH] add Yeti as a pipe function --- example/main.go | 22 ++++++++++++++++++++++ internal/internalpipe/pipe.go | 7 ------- internal/internalpipe/snag.go | 25 +++++++++++++++++++++++++ internal/internalpipe/yeet.go | 2 +- pkg/pipe/interface.go | 8 ++++++++ pkg/pipe/yeet.go | 19 +++---------------- 6 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 example/main.go diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..d855ff6 --- /dev/null +++ b/example/main.go @@ -0,0 +1,22 @@ +package main + +import ( + "errors" + "fmt" + + "github.com/koss-null/funcfrog/pkg/pipe" +) + +func main() { + p := pipe.Slice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9}) + y := pipe.NewYeti() + res := p.Yeti(y).Map(func(i int) int { + if i < 0 { + y.Yeet(errors.New("omg the value is negative")) + } + return 2 * i + }).Snag(func(err error) { + fmt.Println("Snagging an error: " + err.Error()) + }).Do() + fmt.Println(res) +} diff --git a/internal/internalpipe/pipe.go b/internal/internalpipe/pipe.go index 841dcc3..f6e3dfd 100644 --- a/internal/internalpipe/pipe.go +++ b/internal/internalpipe/pipe.go @@ -2,7 +2,6 @@ package internalpipe import ( "math" - "unsafe" "golang.org/x/exp/constraints" ) @@ -62,12 +61,6 @@ func (p Pipe[T]) Count() int { return cnt } -// Sang ads error handler to a current Pipe step. -func (p Pipe[T]) Snag(h ErrHandler) Pipe[T] { - p.y.SnagPipe(unsafe.Pointer(p.prevP), h) - return p -} - // limit returns the upper border limit as the pipe evaluation limit. func (p *Pipe[T]) limit() int { switch { diff --git a/internal/internalpipe/snag.go b/internal/internalpipe/snag.go index e69de29..f82eecb 100644 --- a/internal/internalpipe/snag.go +++ b/internal/internalpipe/snag.go @@ -0,0 +1,25 @@ +package internalpipe + +import "unsafe" + +// Sang ads error handler to a current Pipe step. +func (p Pipe[T]) Snag(h ErrHandler) Pipe[T] { + // todo: think about NPE here + p.y.SnagPipe(unsafe.Pointer(p.prevP), h) + return p +} + +type YeetSnag interface { + // yeet an error + Yeet(err error) + // snag and handle the error + Snag(ErrHandler) +} + +// Yeti adds Yeti error handler to the pipe. +// If some other handlers were set before, they are handled by the Snag +func (p Pipe[T]) Yeti(y YeetSnag) Pipe[T] { + // todo: save previous y + p.y = y.(yeti) + return p +} diff --git a/internal/internalpipe/yeet.go b/internal/internalpipe/yeet.go index 5dd30b3..e7a03cd 100644 --- a/internal/internalpipe/yeet.go +++ b/internal/internalpipe/yeet.go @@ -5,7 +5,7 @@ import ( "unsafe" ) -type ErrHandler func(err error) +type ErrHandler func(error) type Yeti struct { Errs []error diff --git a/pkg/pipe/interface.go b/pkg/pipe/interface.go index 314f31b..fc8f267 100644 --- a/pkg/pipe/interface.go +++ b/pkg/pipe/interface.go @@ -1,5 +1,7 @@ package pipe +import "github.com/koss-null/funcfrog/internal/internalpipe" + // Piper interface contains all methods of a pipe with determened length. type Piper[T any] interface { doer[T] @@ -19,6 +21,7 @@ type Piper[T any] interface { promicer[T] eraser[Piper[any]] snagger[Piper[T]] + yeti[Piper[T]] } // PiperNoLen represents methods available to a Pipe type with no length determened. @@ -36,6 +39,7 @@ type PiperNoLen[T any] interface { eraser[PiperNoLen[any]] snagger[PiperNoLen[T]] + yeti[PiperNoLen[T]] } type paralleller[T, PiperT any] interface { @@ -97,3 +101,7 @@ type promicer[T any] interface { type snagger[PiperT any] interface { Snag(func(error)) PiperT } + +type yeti[PiperT any] interface { + Yeti(y internalpipe.YeetSnag) PiperT +} diff --git a/pkg/pipe/yeet.go b/pkg/pipe/yeet.go index 7a1a2c6..4f2697c 100644 --- a/pkg/pipe/yeet.go +++ b/pkg/pipe/yeet.go @@ -1,8 +1,6 @@ package pipe import ( - "sync" - "github.com/koss-null/funcfrog/internal/internalpipe" ) @@ -11,18 +9,7 @@ const ( initHandlersAmount = 5 ) -type Yeti interface { - // yeet an error - Yeet(err error) - // snag and handle the error - Snag(handler func(err error)) -} - -// FIXME -func Yeet() Yeti { - return &internalpipe.Yeti{ - Errs: make(map[*any][]error, initErrsAmount), - Handlers: make(map[*any][]internalpipe.ErrHandler, initHandlersAmount), - Mx: &sync.Mutex{}, - } +// NewYeti creates a brand new Yeti - an object for error handling. +func NewYeti() internalpipe.YeetSnag { + return internalpipe.NewYeti() }