From 6a50fb0025f982448093f6aeb3dd25df709a0973 Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Thu, 30 Jan 2025 22:49:19 +1100 Subject: [PATCH] Added itrs:tap --- _docs/mod/itrs.md | 11 ++++++++++- ucl/builtins/itrs.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/_docs/mod/itrs.md b/_docs/mod/itrs.md index df4fc9b..b20b7f4 100644 --- a/_docs/mod/itrs.md +++ b/_docs/mod/itrs.md @@ -11,10 +11,19 @@ itrs:from LIST Returns an iterator which will step through the elements of LIST. +### tap + +``` +itrs:tap ITR BLOCK +``` + +Returns an iterator which will execute BLOCK for each element consumed. The elements are consumed from the +iterator ITR. BLOCK will only be executed when the element is consumed. + ### to-list ``` -lists:to-list ITR +itrs:to-list ITR ``` Consume the elements of the iterator ITR and return the elements as a list. \ No newline at end of file diff --git a/ucl/builtins/itrs.go b/ucl/builtins/itrs.go index a58bb50..7614204 100644 --- a/ucl/builtins/itrs.go +++ b/ucl/builtins/itrs.go @@ -10,6 +10,7 @@ func Itrs() ucl.Module { Name: "itrs", Builtins: map[string]ucl.BuiltinHandler{ "from": iterFrom, + "tap": iterTap, "to-list": iterToList, }, } @@ -47,6 +48,45 @@ func (f *fromIterator) Next(ctx context.Context) (ucl.Object, error) { return v, nil } +func iterTap(ctx context.Context, args ucl.CallArgs) (any, error) { + var ( + src ucl.Iterable + tap ucl.Invokable + ) + + if err := args.Bind(&src, &tap); err != nil { + return nil, err + } + + return &tappedIterator{src, tap}, nil +} + +type tappedIterator struct { + src ucl.Iterable + tap ucl.Invokable +} + +func (f *tappedIterator) String() string { + return "tappedIterator{}" +} + +func (f *tappedIterator) HasNext() bool { + return f.src.HasNext() +} + +func (f *tappedIterator) Next(ctx context.Context) (ucl.Object, error) { + v, err := f.src.Next(ctx) + if err != nil { + return nil, err + } + + if _, err := f.tap.Invoke(ctx, v); err != nil { + return nil, err + } + + return v, nil +} + func iterToList(ctx context.Context, args ucl.CallArgs) (any, error) { var itr ucl.Iterable if err := args.Bind(&itr); err != nil {