// 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 || name == indexName return yes } func (it *ListIterator) CallOperation(name string, args []any) (v any, err error) { switch name { case resetName: v, err = it.Reset() case indexName: v = it.Index() default: 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 }