new iter-iter iterator and kern.func-info module
This commit is contained in:
+132
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||
// All rights reserved.
|
||||
|
||||
// iter-iter.go
|
||||
package expr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"git.portale-stac.it/go-pkg/expr/kern"
|
||||
)
|
||||
|
||||
type IterIter struct {
|
||||
it kern.Iterator
|
||||
count int64
|
||||
index int64
|
||||
ctx kern.ExprContext
|
||||
op kern.Functor
|
||||
opName string
|
||||
args map[string]any
|
||||
current any
|
||||
}
|
||||
|
||||
func NewIterIter(it kern.Iterator, ctx kern.ExprContext, op kern.Functor, args map[string]any) (iter kern.Iterator, err error) {
|
||||
var opName string
|
||||
if op != nil {
|
||||
if f := op.GetFunc(); f != nil {
|
||||
opName = f.Name()
|
||||
// } else {
|
||||
// return nil, fmt.Errorf("invalid functor argument for iter-iter: expected kern.Functor, got %T", args["op"])
|
||||
}
|
||||
}
|
||||
if len(opName) == 0 {
|
||||
opName = "anonymous"
|
||||
}
|
||||
iter = &IterIter{it: it, count: 0, index: -1, ctx: ctx, op: op, opName: opName, args: args}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (it *IterIter) String() string {
|
||||
return fmt.Sprintf("$(%s)", it.it)
|
||||
}
|
||||
|
||||
func (it *IterIter) TypeName() string {
|
||||
return "IterIter"
|
||||
}
|
||||
|
||||
func (it *IterIter) HasOperation(name string) bool {
|
||||
return HasStandardOperation(name)
|
||||
}
|
||||
|
||||
func (it *IterIter) CallOperation(name string, args map[string]any) (v any, err error) {
|
||||
switch name {
|
||||
case kern.NextName:
|
||||
v, err = it.Next()
|
||||
case kern.ResetName:
|
||||
err = it.Reset()
|
||||
case kern.CleanName:
|
||||
err = it.Clean()
|
||||
case kern.IndexName:
|
||||
v = int64(it.Index())
|
||||
case kern.CurrentName:
|
||||
v, err = it.Current()
|
||||
case kern.CountName:
|
||||
v = it.count
|
||||
default:
|
||||
err = kern.ErrNoOperation(name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *IterIter) Current() (item any, err error) {
|
||||
if it.current != nil {
|
||||
item = it.current
|
||||
} else if it.op != nil {
|
||||
if item, err = it.op.InvokeNamed(it.ctx, it.opName, it.args); err == nil {
|
||||
it.current = item
|
||||
}
|
||||
} else {
|
||||
var exists bool
|
||||
if it.current, exists = it.ctx.GetVar("_"); !exists {
|
||||
err = fmt.Errorf("current item not available")
|
||||
} else {
|
||||
item = it.current
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *IterIter) Next() (item any, err error) {
|
||||
var src any
|
||||
|
||||
it.current = nil
|
||||
ctx := it.ctx
|
||||
for src, err = it.it.Next(); src == nil && err == nil; src, err = it.it.Next() {
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if src == nil {
|
||||
err = io.EOF
|
||||
} else {
|
||||
ctx.UnsafeSetVar("_", src)
|
||||
ctx.UnsafeSetVar("__", it.it.Index())
|
||||
ctx.UnsafeSetVar("_#", it.it.Count())
|
||||
item, err = it.Current()
|
||||
ctx.DeleteVar("_#")
|
||||
ctx.DeleteVar("__")
|
||||
ctx.DeleteVar("_")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (it *IterIter) Index() int64 {
|
||||
return it.index
|
||||
}
|
||||
|
||||
func (it *IterIter) Count() int64 {
|
||||
return it.count
|
||||
}
|
||||
|
||||
func (it *IterIter) Reset() error {
|
||||
it.index = -1
|
||||
it.count = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (it *IterIter) Clean() error {
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user