63 lines
1.2 KiB
Go
63 lines
1.2 KiB
Go
// 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
|
|
}
|