// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // data-cursors.go package expr import ( "io" ) const ( initName = "init" nextName = "next" currentName = "current" ) type dataCursor struct { ds map[any]*term ctx ExprContext index int resource any nextFunc Functor currentFunc Functor } func newDataCursor(ctx ExprContext) (dc *dataCursor) { dc = &dataCursor{ index: -1, ctx: ctx.Clone(), } return } func (dc *dataCursor) String() string { return "$(...)" } func (dc *dataCursor) Current() (item any, err error) { // must return io.EOF at the last item ctx := cloneContext(dc.ctx) if item, err = dc.currentFunc.Invoke(ctx, currentName, []any{}); err == nil && item == nil { err = io.EOF } exportObjects(dc.ctx, ctx) return } func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after the last item ctx := cloneContext(dc.ctx) if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{}); err == nil { if item == nil { err = io.EOF } else { dc.index++ } exportObjects(dc.ctx, ctx) } return } func (dc *dataCursor) Index() int { return dc.index }