data-cursor.go: add item mapping support
This commit is contained in:
parent
8547248ea2
commit
9a95a837f6
@ -133,39 +133,60 @@ func (dc *dataCursor) Current() (item any, err error) { // must return io.EOF at
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *dataCursor) _Next() (item any, err error) { // must return io.EOF after the last item
|
// func (dc *dataCursor) _Next() (item any, err error) { // must return io.EOF after the last item
|
||||||
if dc.resource != nil {
|
// if dc.resource != nil {
|
||||||
ctx := cloneContext(dc.ctx)
|
// ctx := cloneContext(dc.ctx)
|
||||||
// fmt.Printf("Entering Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0))
|
// // fmt.Printf("Entering Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0))
|
||||||
if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{dc.resource}); err == nil {
|
// if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{dc.resource}); err == nil {
|
||||||
if item == nil {
|
// if item == nil {
|
||||||
err = io.EOF
|
// err = io.EOF
|
||||||
} else {
|
// } else {
|
||||||
dc.index++
|
// dc.index++
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
// fmt.Printf("Exiting Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0))
|
// // fmt.Printf("Exiting Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0))
|
||||||
exportObjects(dc.ctx, ctx)
|
// exportObjects(dc.ctx, ctx)
|
||||||
// fmt.Printf("Outer-Ctx [%p]: %s\n", dc.ctx, CtxToString(dc.ctx, 0))
|
// // fmt.Printf("Outer-Ctx [%p]: %s\n", dc.ctx, CtxToString(dc.ctx, 0))
|
||||||
} else {
|
// } else {
|
||||||
err = errInvalidDataSource()
|
// err = errInvalidDataSource()
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (dc *dataCursor) _filter(item any) (filterdItem any, err error) {
|
||||||
|
// if filter, ok := dc.ds[filterName]; ok {
|
||||||
|
// ctx := cloneContext(dc.ctx)
|
||||||
|
// filterdItem, err = filter.Invoke(ctx, filterName, []any{item, dc.index})
|
||||||
|
// } else {
|
||||||
|
// filterdItem = item
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (dc *dataCursor) checkFilter(filter Functor, item any) (accepted bool, err error) {
|
||||||
|
var v any
|
||||||
|
var ok bool
|
||||||
|
ctx := cloneContext(dc.ctx)
|
||||||
|
if v, err = filter.Invoke(ctx, filterName, []any{item, dc.index}); err == nil && v != nil {
|
||||||
|
if accepted, ok = v.(bool); !ok {
|
||||||
|
accepted = true // NOTE: A non-boolean value that is not nil means the item has been accepted
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
func (dc *dataCursor) mapItem(mapper Functor, item any) (mappedItem any, err error) {
|
||||||
const filterName = "filter"
|
ctx := cloneContext(dc.ctx)
|
||||||
func (dc *dataCursor) filter(item any) (filterdItem any, err error) {
|
mappedItem, err = mapper.Invoke(ctx, mapName, []any{item, dc.index});
|
||||||
if filter, ok := dc.ds[filterName]; ok {
|
|
||||||
ctx := cloneContext(dc.ctx)
|
|
||||||
filterdItem, err = filter.Invoke(ctx, filterName, []any{item, dc.index});
|
|
||||||
} else {
|
|
||||||
filterdItem = item
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after the last item
|
func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after the last item
|
||||||
|
var accepted bool
|
||||||
if dc.resource != nil {
|
if dc.resource != nil {
|
||||||
|
filter := dc.ds[filterName]
|
||||||
|
mapper := dc.ds[mapName]
|
||||||
|
|
||||||
for item == nil && err == nil {
|
for item == nil && err == nil {
|
||||||
ctx := cloneContext(dc.ctx)
|
ctx := cloneContext(dc.ctx)
|
||||||
if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{dc.resource}); err == nil {
|
if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{dc.resource}); err == nil {
|
||||||
@ -173,7 +194,14 @@ func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after
|
|||||||
err = io.EOF
|
err = io.EOF
|
||||||
} else {
|
} else {
|
||||||
dc.index++
|
dc.index++
|
||||||
item, err = dc.filter(item)
|
if filter != nil {
|
||||||
|
if accepted, err = dc.checkFilter(filter, item); err != nil || !accepted {
|
||||||
|
item = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if item != nil && mapper != nil {
|
||||||
|
item, err = dc.mapItem(mapper, item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exportObjects(dc.ctx, ctx)
|
exportObjects(dc.ctx, ctx)
|
||||||
|
@ -19,6 +19,8 @@ const (
|
|||||||
currentName = "current"
|
currentName = "current"
|
||||||
indexName = "index"
|
indexName = "index"
|
||||||
countName = "count"
|
countName = "count"
|
||||||
|
filterName = "filter"
|
||||||
|
mapName = "map"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Iterator interface {
|
type Iterator interface {
|
||||||
|
@ -20,9 +20,9 @@ func TestIteratorParser(t *testing.T) {
|
|||||||
/* 9 */ {`include "test-resources/file-reader.expr"; it=$(ds,"test-resources/int.list"); it.clean`, true, nil},
|
/* 9 */ {`include "test-resources/file-reader.expr"; it=$(ds,"test-resources/int.list"); it.clean`, true, nil},
|
||||||
/* 10 */ {`it=$(1,2,3); it++`, int64(1), nil},
|
/* 10 */ {`it=$(1,2,3); it++`, int64(1), nil},
|
||||||
/* 11 */ {`it=$(1,2,3); it++; it.reset; it++`, int64(1), nil},
|
/* 11 */ {`it=$(1,2,3); it++; it.reset; it++`, int64(1), nil},
|
||||||
/* 12 */ {`include "test-resources/filter.expr"; it=$(ds,10); it++`, int64(1), nil},
|
/* 12 */ {`include "test-resources/filter.expr"; it=$(ds,10); it++`, int64(2), nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
//runTestSuiteSpec(t, section, inputs, 12)
|
runTestSuiteSpec(t, section, inputs, 12)
|
||||||
runTestSuite(t, section, inputs)
|
//runTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user