expr/iter-list.go

87 lines
1.6 KiB
Go

// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// iter-list.go
package expr
import (
"fmt"
"io"
)
type ListIterator struct {
a *ListType
index int
}
func NewListIterator(list *ListType) *ListIterator {
return &ListIterator{a: list, index: 0}
}
func NewArrayIterator(array []any) *ListIterator {
return &ListIterator{a: (*ListType)(&array), index: 0}
}
func NewAnyIterator(value any) (it *ListIterator) {
if value == nil {
it = NewArrayIterator([]any{})
} else if list, ok := value.(*ListType); ok {
it = NewListIterator(list)
} else if array, ok := value.([]any); ok {
it = NewArrayIterator(array)
} else if it1, ok := value.(*ListIterator); ok {
it = it1
} else {
it = NewArrayIterator([]any{value})
}
return
}
func (it *ListIterator) String() string {
var l = 0
if it.a != nil {
l = len(*it.a)
}
return fmt.Sprintf("$(#%d)", l)
}
func (it *ListIterator) HasOperation(name string) bool {
yes := name == resetName
return yes
}
func (it *ListIterator) CallOperation(name string, args []any) (v any, err error) {
if name == resetName {
v, err = it.Reset()
} else {
err = errNoOperation(name)
}
return
}
func (it *ListIterator) Current() (item any, err error) {
a := *(it.a)
if it.index >= 0 && it.index < len(a) {
item = a[it.index]
} else {
err = io.EOF
}
return
}
func (it *ListIterator) Next() (item any, err error) {
if item, err = it.Current(); err != io.EOF {
it.index++
}
return
}
func (it *ListIterator) Index() int {
return it.index - 1
}
func (it *ListIterator) Reset() (bool, error) {
it.index = 0
return true, nil
}