// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // iterator.go package kern import ( // "errors" "fmt" "slices" ) // Operator names const ( InitName = "init" CleanName = "clean" ResetName = "reset" NextName = "next" CurrentName = "current" IndexName = "index" CountName = "count" FilterName = "filter" MapName = "map" KeyName = "key" ValueName = "value" ) type Iterator interface { Typer fmt.Stringer Next() (item any, err error) // must return io.EOF after the last item Current() (item any, err error) Index() int64 Count() int64 HasOperation(name string) bool CallOperation(name string, args map[string]any) (value any, err error) } type ExtIterator interface { Iterator Reset() error Clean() error } func ErrNoOperation(name string) error { return fmt.Errorf("no %s() function defined in the data-source", name) } func IsIterator(v any) (ok bool) { _, ok = v.(Iterator) return } type IteratorBase struct { ItemIndex int64 ItemCount int64 current any } func (it *IteratorBase) Current() (item any, err error) { return it.current, nil } func (it *IteratorBase) Index() int64 { return it.ItemIndex } func (it *IteratorBase) Count() int64 { return it.ItemCount } func (it *IteratorBase) HasOperation(name string) bool { return slices.Contains([]string{NextName, IndexName, CountName, CurrentName}, name) } func (it *IteratorBase) Clean() (err error) { return } func (it *IteratorBase) Reset() (err error) { it.ItemIndex = -1 it.ItemCount = 0 it.current = nil return } func (it *IteratorBase) Increment() { it.ItemIndex++ it.ItemCount++ } func (it *IteratorBase) SetCurrent(v any) { it.current = v }