renaming: AsyncResultIterator => AsyncResultIter to have it consistent with other iterators

This commit is contained in:
Marcin Czenko 2025-06-24 15:24:55 +02:00
parent c5c1f979c0
commit 28ccfb1744
No known key found for this signature in database
GPG Key ID: 33DEA0C8E30937C0
16 changed files with 113 additions and 117 deletions

View File

@ -121,13 +121,13 @@ func indexToPos(steps, idx, step: int): int {.inline.} =
proc getPendingBlocks( proc getPendingBlocks(
self: Erasure, manifest: Manifest, indices: seq[int] self: Erasure, manifest: Manifest, indices: seq[int]
): AsyncResultIterator[(?!bt.Block, int)] = ): AsyncResultIter[(?!bt.Block, int)] =
## Get pending blocks iterator ## Get pending blocks iterator
## ##
if indices.len == 0: if indices.len == 0:
trace "No indices to fetch blocks for", treeCid = manifest.treeCid trace "No indices to fetch blocks for", treeCid = manifest.treeCid
return AsyncResultIterator[(?!bt.Block, int)].empty() return AsyncResultIter[(?!bt.Block, int)].empty()
var pendingBlocks: seq[Future[(?!bt.Block, int)].Raising([CancelledError])] = @[] var pendingBlocks: seq[Future[(?!bt.Block, int)].Raising([CancelledError])] = @[]
@ -162,8 +162,8 @@ proc getPendingBlocks(
# but we check for that at the very beginning - # but we check for that at the very beginning -
# thus, if this happens, we raise an assert # thus, if this happens, we raise an assert
raiseAssert("fatal: pendingBlocks is empty - this should never happen") raiseAssert("fatal: pendingBlocks is empty - this should never happen")
AsyncResultIterator[(?!bt.Block, int)].new(genNext, isFinished) AsyncResultIter[(?!bt.Block, int)].new(genNext, isFinished)
proc prepareEncodingData( proc prepareEncodingData(
self: Erasure, self: Erasure,

View File

@ -154,9 +154,7 @@ method hasBlock*(
method listBlocks*( method listBlocks*(
self: BlockStore, blockType = BlockType.Manifest self: BlockStore, blockType = BlockType.Manifest
): Future[?!AsyncResultIterator[Cid]] {. ): Future[?!AsyncResultIter[Cid]] {.base, async: (raises: [CancelledError]), gcsafe.} =
base, async: (raises: [CancelledError]), gcsafe
.} =
## Get the list of blocks in the BlockStore. This is an intensive operation ## Get the list of blocks in the BlockStore. This is an intensive operation
## ##

View File

@ -139,7 +139,7 @@ func cids(self: CacheStore): (iterator (): Cid {.gcsafe, raises: [].}) =
method listBlocks*( method listBlocks*(
self: CacheStore, blockType = BlockType.Manifest self: CacheStore, blockType = BlockType.Manifest
): Future[?!AsyncResultIterator[Cid]] {.async: (raises: [CancelledError]).} = ): Future[?!AsyncResultIter[Cid]] {.async: (raises: [CancelledError]).} =
## Get the list of blocks in the BlockStore. This is an intensive operation ## Get the list of blocks in the BlockStore. This is an intensive operation
## ##
@ -152,7 +152,7 @@ method listBlocks*(
success(cids()) success(cids())
let iter = await ( let iter = await (
AsyncResultIterator[Cid].new(genNext, isFinished).filter( AsyncResultIter[Cid].new(genNext, isFinished).filter(
proc(cid: ?!Cid): Future[bool] {.async: (raises: [CancelledError]).} = proc(cid: ?!Cid): Future[bool] {.async: (raises: [CancelledError]).} =
without cid =? cid, err: without cid =? cid, err:
trace "Cannot get Cid from the iterator", err = err.msg trace "Cannot get Cid from the iterator", err = err.msg

View File

@ -18,7 +18,7 @@ import pkg/questionable/results
import ./repostore import ./repostore
import ../utils/timer import ../utils/timer
import ../utils/asyncresultiterator import ../utils/asyncresultiter
import ../clock import ../clock
import ../logutils import ../logutils
import ../systemclock import ../systemclock

View File

@ -19,7 +19,7 @@ import ../blockexchange
import ../logutils import ../logutils
import ../merkletree import ../merkletree
import ../utils/asyncheapqueue import ../utils/asyncheapqueue
import ../utils/asyncresultiterator import ../utils/asyncresultiter
import ./blockstore import ./blockstore
export blockstore, blockexchange, asyncheapqueue export blockstore, blockexchange, asyncheapqueue
@ -127,7 +127,7 @@ method ensureExpiry*(
method listBlocks*( method listBlocks*(
self: NetworkStore, blockType = BlockType.Manifest self: NetworkStore, blockType = BlockType.Manifest
): Future[?!AsyncResultIterator[Cid]] {.async: (raw: true, raises: [CancelledError]).} = ): Future[?!AsyncResultIter[Cid]] {.async: (raw: true, raises: [CancelledError]).} =
self.localStore.listBlocks(blockType) self.localStore.listBlocks(blockType)
method delBlock*( method delBlock*(

View File

@ -4,16 +4,16 @@ import pkg/chronos
import pkg/chronicles import pkg/chronicles
import pkg/datastore/typedds import pkg/datastore/typedds
import ../utils/asyncresultiterator import ../utils/asyncresultiter
{.push raises: [].} {.push raises: [].}
type KeyVal*[T] = tuple[key: Key, value: T] type KeyVal*[T] = tuple[key: Key, value: T]
proc toAsyncResultIterator*[T]( proc toAsyncResultIter*[T](
queryIter: QueryIter[T], finishOnErr: bool = true queryIter: QueryIter[T], finishOnErr: bool = true
): Future[?!AsyncResultIterator[QueryResponse[T]]] {.async: (raises: [CancelledError]).} = ): Future[?!AsyncResultIter[QueryResponse[T]]] {.async: (raises: [CancelledError]).} =
## Converts `QueryIter[T]` to `AsyncResultIterator[QueryResponse[T]]` and automatically ## Converts `QueryIter[T]` to `AsyncResultIter[QueryResponse[T]]` and automatically
## runs dispose whenever `QueryIter` finishes or whenever an error occurs (only ## runs dispose whenever `QueryIter` finishes or whenever an error occurs (only
## if the flag finishOnErr is set to true) ## if the flag finishOnErr is set to true)
## ##
@ -22,7 +22,7 @@ proc toAsyncResultIterator*[T](
trace "Disposing iterator" trace "Disposing iterator"
if error =? (await queryIter.dispose()).errorOption: if error =? (await queryIter.dispose()).errorOption:
return failure(error) return failure(error)
return success(AsyncResultIterator[QueryResponse[T]].empty()) return success(AsyncResultIter[QueryResponse[T]].empty())
var errOccurred = false var errOccurred = false
@ -42,11 +42,11 @@ proc toAsyncResultIterator*[T](
proc isFinished(): bool = proc isFinished(): bool =
queryIter.finished queryIter.finished
AsyncResultIterator[QueryResponse[T]].new(genNext, isFinished).success AsyncResultIter[QueryResponse[T]].new(genNext, isFinished).success
proc filterSuccess*[T]( proc filterSuccess*[T](
iter: AsyncResultIterator[QueryResponse[T]] iter: AsyncResultIter[QueryResponse[T]]
): Future[AsyncResultIterator[tuple[key: Key, value: T]]] {. ): Future[AsyncResultIter[tuple[key: Key, value: T]]] {.
async: (raises: [CancelledError]) async: (raises: [CancelledError])
.} = .} =
## Filters out any items that are not success ## Filters out any items that are not success

View File

@ -295,12 +295,12 @@ method hasBlock*(
method listBlocks*( method listBlocks*(
self: RepoStore, blockType = BlockType.Manifest self: RepoStore, blockType = BlockType.Manifest
): Future[?!AsyncResultIterator[Cid]] {.async: (raises: [CancelledError]).} = ): Future[?!AsyncResultIter[Cid]] {.async: (raises: [CancelledError]).} =
## Get the list of blocks in the RepoStore. ## Get the list of blocks in the RepoStore.
## This is an intensive operation ## This is an intensive operation
## ##
var iter = AsyncResultIterator[Cid]() var iter = AsyncResultIter[Cid]()
let key = let key =
case blockType case blockType
@ -346,7 +346,7 @@ proc blockRefCount*(self: RepoStore, cid: Cid): Future[?!Natural] {.async.} =
method getBlockExpirations*( method getBlockExpirations*(
self: RepoStore, maxNumber: int, offset: int self: RepoStore, maxNumber: int, offset: int
): Future[?!AsyncResultIterator[BlockExpiration]] {. ): Future[?!AsyncResultIter[BlockExpiration]] {.
async: (raises: [CancelledError]), base, gcsafe async: (raises: [CancelledError]), base, gcsafe
.} = .} =
## Get iterator with block expirations ## Get iterator with block expirations
@ -360,11 +360,11 @@ method getBlockExpirations*(
error "Unable to execute block expirations query", err = err.msg error "Unable to execute block expirations query", err = err.msg
return failure(err) return failure(err)
without asyncQueryIter =? (await queryIter.toAsyncResultIterator()), err: without asyncQueryIter =? (await queryIter.toAsyncResultIter()), err:
error "Unable to convert QueryIter to AsyncIter", err = err.msg error "Unable to convert QueryIter to AsyncIter", err = err.msg
return failure(err) return failure(err)
let filteredIter: AsyncResultIterator[KeyVal[BlockMetadata]] = let filteredIter: AsyncResultIter[KeyVal[BlockMetadata]] =
await asyncQueryIter.filterSuccess() await asyncQueryIter.filterSuccess()
proc mapping( proc mapping(

View File

@ -19,9 +19,9 @@ import pkg/chronos
import ./utils/asyncheapqueue import ./utils/asyncheapqueue
import ./utils/fileutils import ./utils/fileutils
import ./utils/iter import ./utils/iter
import ./utils/asyncresultiterator import ./utils/asyncresultiter
export asyncheapqueue, fileutils, iter, asyncresultiterator, chronos export asyncheapqueue, fileutils, iter, asyncresultiter, chronos
when defined(posix): when defined(posix):
import os, posix import os, posix

View File

@ -40,11 +40,9 @@ import ./iter
## - empty - to create an empty async iterator (AsyncIter) ## - empty - to create an empty async iterator (AsyncIter)
type type
AsyncIterFunc[T, U] = AsyncIterFunc[T, U] = proc(fut: T): Future[U] {.async.}
proc(fut: T): Future[U] {.async.}
AsyncIterIsFinished = proc(): bool {.raises: [], gcsafe.} AsyncIterIsFinished = proc(): bool {.raises: [], gcsafe.}
AsyncIterGenNext[T] = AsyncIterGenNext[T] = proc(): Future[T] {.async.}
proc(): Future[T] {.async.}
AsyncIter*[T] = ref object AsyncIter*[T] = ref object
finished: bool finished: bool
@ -218,4 +216,4 @@ proc empty*[T](_: type AsyncIter[T]): AsyncIter[T] =
proc isFinished(): bool = proc isFinished(): bool =
true true
AsyncIter[T].new(genNext, isFinished) AsyncIter[T].new(genNext, isFinished)

View File

@ -17,11 +17,11 @@ import pkg/chronos
import ./iter import ./iter
## AsyncResultIterator[T] is similar to `AsyncIterator[Future[T]]` ## AsyncResultIter[T] is similar to `AsyncIterator[Future[T]]`
## but does not throw exceptions others than CancelledError. ## but does not throw exceptions others than CancelledError.
## ##
## Instead of throwing exception, it uses Result to communicate errors ( ## Instead of throwing exception, it uses Result to communicate errors (
## thus the name AsyncResultIterator). ## thus the name AsyncResultIter).
## ##
## Public interface: ## Public interface:
## ##
@ -29,58 +29,57 @@ import ./iter
## - next - allows to set a custom function to be called when the next item is requested ## - next - allows to set a custom function to be called when the next item is requested
## ##
## Operations: ## Operations:
## - new - to create a new async iterator (AsyncResultIterator) ## - new - to create a new async iterator (AsyncResultIter)
## - finish - to finish the async iterator ## - finish - to finish the async iterator
## - finished - to check if the async iterator is finished ## - finished - to check if the async iterator is finished
## - next - to get the next item from the async iterator ## - next - to get the next item from the async iterator
## - items - to iterate over the async iterator ## - items - to iterate over the async iterator
## - pairs - to iterate over the async iterator and return the index of each item ## - pairs - to iterate over the async iterator and return the index of each item
## - mapFuture - to convert a (raising) Future[T] to a (raising) Future[U] using a function fn: auto -> Future[U] - we use auto to handle both raising and non-raising futures ## - mapFuture - to convert a (raising) Future[T] to a (raising) Future[U] using a function fn: auto -> Future[U] - we use auto to handle both raising and non-raising futures
## - mapAsync - to convert a regular sync iterator (Iter) to an async iter (AsyncResultIterator) ## - mapAsync - to convert a regular sync iterator (Iter) to an async iterator (AsyncResultIter)
## - map - to convert one async iterator (AsyncResultIterator) to another async iter (AsyncResultIterator) ## - map - to convert one async iterator (AsyncResultIter) to another async iterator (AsyncResultIter)
## - mapFilter - to convert one async iterator (AsyncResultIterator) to another async iter (AsyncResultIterator) and apply filtering at the same time ## - mapFilter - to convert one async iterator (AsyncResultIter) to another async iterator (AsyncResultIter) and apply filtering at the same time
## - filter - to filter an async iterator (AsyncResultIterator) returning another async iterator (AsyncResultIterator) ## - filter - to filter an async iterator (AsyncResultIter) and return another async iterator (AsyncResultIter)
## - delayBy - to delay each item returned by async iter by a given duration ## - delayBy - to delay each item returned by async iterator by a given duration
## - empty - to create an empty async iterator (AsyncResultIterator) ## - empty - to create an empty async iterator (AsyncResultIter)
type type
AsyncResultIteratorFunc[T, U] = AsyncResultIterFunc[T, U] =
proc(fut: T): Future[U] {.async: (raises: [CancelledError]), gcsafe, closure.} proc(fut: T): Future[U] {.async: (raises: [CancelledError]).}
AsyncResultIteratorIsFinished = proc(): bool {.raises: [], gcsafe, closure.} AsyncResultIterIsFinished = proc(): bool {.raises: [], gcsafe.}
AsyncResultIteratorGenNext[T] = AsyncResultIterGenNext[T] = proc(): Future[T] {.async: (raises: [CancelledError]).}
proc(): Future[T] {.async: (raises: [CancelledError]), gcsafe.}
AsyncResultIterator*[T] = ref object AsyncResultIter*[T] = ref object
finished: bool finished: bool
next*: AsyncResultIteratorGenNext[?!T] next*: AsyncResultIterGenNext[?!T]
proc flatMap[T, U]( proc flatMap[T, U](
fut: auto, fn: AsyncResultIteratorFunc[?!T, ?!U] fut: auto, fn: AsyncResultIterFunc[?!T, ?!U]
): Future[?!U] {.async: (raises: [CancelledError]).} = ): Future[?!U] {.async: (raises: [CancelledError]).} =
let t = await fut let t = await fut
await fn(t) await fn(t)
proc flatMap[T, U]( proc flatMap[T, U](
fut: auto, fn: AsyncResultIteratorFunc[?!T, Option[?!U]] fut: auto, fn: AsyncResultIterFunc[?!T, Option[?!U]]
): Future[Option[?!U]] {.async: (raises: [CancelledError]).} = ): Future[Option[?!U]] {.async: (raises: [CancelledError]).} =
let t = await fut let t = await fut
await fn(t) await fn(t)
######################################################################## ########################################################################
## AsyncResultIterator public interface methods ## AsyncResultIter public interface methods
######################################################################## ########################################################################
proc new*[T]( proc new*[T](
_: type AsyncResultIterator[T], _: type AsyncResultIter[T],
genNext: AsyncResultIteratorGenNext[?!T], genNext: AsyncResultIterGenNext[?!T],
isFinished: IsFinished, isFinished: AsyncResultIterIsFinished,
finishOnErr: bool = true, finishOnErr: bool = true,
): AsyncResultIterator[T] = ): AsyncResultIter[T] =
## Creates a new Iter using elements returned by supplier function `genNext`. ## Creates a new Iter using elements returned by supplier function `genNext`.
## Iter is finished whenever `isFinished` returns true. ## Iter is finished whenever `isFinished` returns true.
## ##
var iter = AsyncResultIterator[T]() var iter = AsyncResultIter[T]()
proc next(): Future[?!T] {.async: (raises: [CancelledError]).} = proc next(): Future[?!T] {.async: (raises: [CancelledError]).} =
try: try:
@ -93,7 +92,7 @@ proc new*[T](
iter.finished = true iter.finished = true
return item return item
else: else:
return failure("AsyncResultIterator is finished but next item was requested") return failure("AsyncResultIter is finished but next item was requested")
except CancelledError as err: except CancelledError as err:
iter.finished = true iter.finished = true
raise err raise err
@ -106,12 +105,12 @@ proc new*[T](
# forward declaration # forward declaration
proc mapAsync*[T, U]( proc mapAsync*[T, U](
iter: Iter[T], fn: AsyncResultIteratorFunc[T, ?!U], finishOnErr: bool = true iter: Iter[T], fn: AsyncResultIterFunc[T, ?!U], finishOnErr: bool = true
): AsyncResultIterator[U] ): AsyncResultIter[U]
proc new*[U, V: Ordinal]( proc new*[U, V: Ordinal](
_: type AsyncResultIterator[U], slice: HSlice[U, V], finishOnErr: bool = true _: type AsyncResultIter[U], slice: HSlice[U, V], finishOnErr: bool = true
): AsyncResultIterator[U] = ): AsyncResultIter[U] =
## Creates new Iter from a slice ## Creates new Iter from a slice
## ##
@ -124,8 +123,8 @@ proc new*[U, V: Ordinal](
) )
proc new*[U, V, S: Ordinal]( proc new*[U, V, S: Ordinal](
_: type AsyncResultIterator[U], a: U, b: V, step: S = 1, finishOnErr: bool = true _: type AsyncResultIter[U], a: U, b: V, step: S = 1, finishOnErr: bool = true
): AsyncResultIterator[U] = ): AsyncResultIter[U] =
## Creates new Iter in range a..b with specified step (default 1) ## Creates new Iter in range a..b with specified step (default 1)
## ##
@ -137,53 +136,53 @@ proc new*[U, V, S: Ordinal](
finishOnErr = finishOnErr, finishOnErr = finishOnErr,
) )
proc finish*[T](self: AsyncResultIterator[T]): void = proc finish*[T](self: AsyncResultIter[T]): void =
self.finished = true self.finished = true
proc finished*[T](self: AsyncResultIterator[T]): bool = proc finished*[T](self: AsyncResultIter[T]): bool =
self.finished self.finished
iterator items*[T](self: AsyncResultIterator[T]): auto {.inline.} = iterator items*[T](self: AsyncResultIter[T]): auto {.inline.} =
while not self.finished: while not self.finished:
yield self.next() yield self.next()
iterator pairs*[T](self: AsyncResultIterator[T]): auto {.inline.} = iterator pairs*[T](self: AsyncResultIter[T]): auto {.inline.} =
var i = 0 var i = 0
while not self.finished: while not self.finished:
yield (i, self.next()) yield (i, self.next())
inc(i) inc(i)
proc mapFuture*[T, U]( proc mapFuture*[T, U](
fut: auto, fn: AsyncResultIteratorFunc[T, U] fut: auto, fn: AsyncResultIterFunc[T, U]
): Future[U] {.async: (raises: [CancelledError]).} = ): Future[U] {.async: (raises: [CancelledError]).} =
let t = await fut let t = await fut
await fn(t) await fn(t)
proc mapAsync*[T, U]( proc mapAsync*[T, U](
iter: Iter[T], fn: AsyncResultIteratorFunc[T, ?!U], finishOnErr: bool = true iter: Iter[T], fn: AsyncResultIterFunc[T, ?!U], finishOnErr: bool = true
): AsyncResultIterator[U] = ): AsyncResultIter[U] =
AsyncResultIterator[U].new( AsyncResultIter[U].new(
genNext = () => fn(iter.next()), genNext = () => fn(iter.next()),
isFinished = () => iter.finished(), isFinished = () => iter.finished(),
finishOnErr = finishOnErr, finishOnErr = finishOnErr,
) )
proc map*[T, U]( proc map*[T, U](
iter: AsyncResultIterator[T], iter: AsyncResultIter[T],
fn: AsyncResultIteratorFunc[?!T, ?!U], fn: AsyncResultIterFunc[?!T, ?!U],
finishOnErr: bool = true, finishOnErr: bool = true,
): AsyncResultIterator[U] = ): AsyncResultIter[U] =
AsyncResultIterator[U].new( AsyncResultIter[U].new(
genNext = () => iter.next().flatMap(fn), genNext = () => iter.next().flatMap(fn),
isFinished = () => iter.finished, isFinished = () => iter.finished,
finishOnErr = finishOnErr, finishOnErr = finishOnErr,
) )
proc mapFilter*[T, U]( proc mapFilter*[T, U](
iter: AsyncResultIterator[T], iter: AsyncResultIter[T],
mapPredicate: AsyncResultIteratorFunc[?!T, Option[?!U]], mapPredicate: AsyncResultIterFunc[?!T, Option[?!U]],
finishOnErr: bool = true, finishOnErr: bool = true,
): Future[AsyncResultIterator[U]] {.async: (raises: [CancelledError]).} = ): Future[AsyncResultIter[U]] {.async: (raises: [CancelledError]).} =
var nextU: Option[?!U] var nextU: Option[?!U]
proc filter(): Future[void] {.async: (raises: [CancelledError]).} = proc filter(): Future[void] {.async: (raises: [CancelledError]).} =
@ -203,13 +202,13 @@ proc mapFilter*[T, U](
nextU.isNone nextU.isNone
await filter() await filter()
AsyncResultIterator[U].new(genNext, isFinished, finishOnErr = finishOnErr) AsyncResultIter[U].new(genNext, isFinished, finishOnErr = finishOnErr)
proc filter*[T]( proc filter*[T](
iter: AsyncResultIterator[T], iter: AsyncResultIter[T],
predicate: AsyncResultIteratorFunc[?!T, bool], predicate: AsyncResultIterFunc[?!T, bool],
finishOnErr: bool = true, finishOnErr: bool = true,
): Future[AsyncResultIterator[T]] {.async: (raises: [CancelledError]).} = ): Future[AsyncResultIter[T]] {.async: (raises: [CancelledError]).} =
proc wrappedPredicate( proc wrappedPredicate(
t: ?!T t: ?!T
): Future[Option[?!T]] {.async: (raises: [CancelledError]).} = ): Future[Option[?!T]] {.async: (raises: [CancelledError]).} =
@ -221,8 +220,8 @@ proc filter*[T](
await mapFilter[T, T](iter, wrappedPredicate, finishOnErr = finishOnErr) await mapFilter[T, T](iter, wrappedPredicate, finishOnErr = finishOnErr)
proc delayBy*[T]( proc delayBy*[T](
iter: AsyncResultIterator[T], d: Duration, finishOnErr: bool = true iter: AsyncResultIter[T], d: Duration, finishOnErr: bool = true
): AsyncResultIterator[T] = ): AsyncResultIter[T] =
## Delays emitting each item by given duration ## Delays emitting each item by given duration
## ##
@ -234,14 +233,14 @@ proc delayBy*[T](
finishOnErr = finishOnErr, finishOnErr = finishOnErr,
) )
proc empty*[T](_: type AsyncResultIterator[T]): AsyncResultIterator[T] = proc empty*[T](_: type AsyncResultIter[T]): AsyncResultIter[T] =
## Creates an empty AsyncResultIterator ## Creates an empty AsyncResultIter
## ##
proc genNext(): Future[?!T] {.async: (raises: [CancelledError]).} = proc genNext(): Future[?!T] {.async: (raises: [CancelledError]).} =
T.failure("Next item requested from an empty AsyncResultIterator") T.failure("Next item requested from an empty AsyncResultIter")
proc isFinished(): bool = proc isFinished(): bool =
true true
AsyncResultIterator[T].new(genNext, isFinished) AsyncResultIter[T].new(genNext, isFinished)

View File

@ -157,7 +157,9 @@ iterator pairs*[T](self: Iter[T]): tuple[key: int, val: T] {.inline.} =
proc map*[T, U](iter: Iter[T], fn: IterFunction[T, U]): Iter[U] = proc map*[T, U](iter: Iter[T], fn: IterFunction[T, U]): Iter[U] =
Iter[U].new(genNext = () => fn(iter.next()), isFinished = () => iter.finished) Iter[U].new(genNext = () => fn(iter.next()), isFinished = () => iter.finished)
proc mapFilter*[T, U](iter: Iter[T], mapPredicate: IterFunction[T, Option[U]]): Iter[U] = proc mapFilter*[T, U](
iter: Iter[T], mapPredicate: IterFunction[T, Option[U]]
): Iter[U] =
var nextUOrErr: Option[?!U] var nextUOrErr: Option[?!U]
proc tryFetch(): void = proc tryFetch(): void =
@ -207,4 +209,4 @@ proc empty*[T](_: type Iter[T]): Iter[T] =
proc isFinished(): bool = proc isFinished(): bool =
true true
Iter[T].new(genNext, isFinished) Iter[T].new(genNext, isFinished)

View File

@ -14,7 +14,7 @@ import pkg/questionable
import pkg/questionable/results import pkg/questionable/results
import pkg/codex/stores/repostore import pkg/codex/stores/repostore
import pkg/codex/utils/asyncresultiterator import pkg/codex/utils/asyncresultiter
type MockRepoStore* = ref object of RepoStore type MockRepoStore* = ref object of RepoStore
delBlockCids*: seq[Cid] delBlockCids*: seq[Cid]
@ -32,7 +32,7 @@ method delBlock*(
method getBlockExpirations*( method getBlockExpirations*(
self: MockRepoStore, maxNumber: int, offset: int self: MockRepoStore, maxNumber: int, offset: int
): Future[?!AsyncResultIterator[BlockExpiration]] {.async: (raises: [CancelledError]).} = ): Future[?!AsyncResultIter[BlockExpiration]] {.async: (raises: [CancelledError]).} =
self.getBeMaxNumber = maxNumber self.getBeMaxNumber = maxNumber
self.getBeOffset = offset self.getBeOffset = offset
@ -41,7 +41,7 @@ method getBlockExpirations*(
limit = min(offset + maxNumber, len(testBlockExpirationsCpy)) limit = min(offset + maxNumber, len(testBlockExpirationsCpy))
let let
iter1 = AsyncResultIterator[int].new(offset ..< limit) iter1 = AsyncResultIter[int].new(offset ..< limit)
iter2 = map[int, BlockExpiration]( iter2 = map[int, BlockExpiration](
iter1, iter1,
proc(i: ?!int): Future[?!BlockExpiration] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!BlockExpiration] {.async: (raises: [CancelledError]).} =

View File

@ -6,7 +6,7 @@ import pkg/chronos
import pkg/datastore/typedds import pkg/datastore/typedds
import pkg/datastore/sql/sqliteds import pkg/datastore/sql/sqliteds
import pkg/codex/stores/queryiterhelper import pkg/codex/stores/queryiterhelper
import pkg/codex/utils/asyncresultiterator import pkg/codex/utils/asyncresultiter
import ../../asynctest import ../../asynctest
import ../helpers import ../helpers
@ -43,7 +43,7 @@ asyncchecksuite "Test QueryIter helper":
queryIter.dispose = () => (disposed = true; iterDispose()) queryIter.dispose = () => (disposed = true; iterDispose())
let let
iter1 = (await toAsyncResultIterator[string](queryIter)).tryGet() iter1 = (await toAsyncResultIter[string](queryIter)).tryGet()
iter2 = await filterSuccess[string](iter1) iter2 = await filterSuccess[string](iter1)
var items = initTable[string, string]() var items = initTable[string, string]()

View File

@ -15,7 +15,7 @@ import pkg/codex/stores
import pkg/codex/stores/repostore/operations import pkg/codex/stores/repostore/operations
import pkg/codex/blocktype as bt import pkg/codex/blocktype as bt
import pkg/codex/clock import pkg/codex/clock
import pkg/codex/utils/asyncresultiterator import pkg/codex/utils/asyncresultiter
import pkg/codex/merkletree/codex import pkg/codex/merkletree/codex
import ../../asynctest import ../../asynctest
@ -293,7 +293,7 @@ asyncchecksuite "RepoStore":
test "Should retrieve block expiration information": test "Should retrieve block expiration information":
proc unpack( proc unpack(
beIter: Future[?!AsyncResultIterator[BlockExpiration]].Raising([CancelledError]) beIter: Future[?!AsyncResultIter[BlockExpiration]].Raising([CancelledError])
): Future[seq[BlockExpiration]] {.async: (raises: [CancelledError]).} = ): Future[seq[BlockExpiration]] {.async: (raises: [CancelledError]).} =
var expirations = newSeq[BlockExpiration](0) var expirations = newSeq[BlockExpiration](0)
without iter =? (await beIter), err: without iter =? (await beIter), err:

View File

@ -1,7 +1,7 @@
import ./utils/testoptions import ./utils/testoptions
import ./utils/testkeyutils import ./utils/testkeyutils
import ./utils/testasyncstatemachine import ./utils/testasyncstatemachine
import ./utils/testasyncresultiterator import ./utils/testasyncresultiter
import ./utils/testtimer import ./utils/testtimer
import ./utils/testtrackedfutures import ./utils/testtrackedfutures

View File

@ -2,14 +2,14 @@ import std/sugar
import pkg/questionable import pkg/questionable
import pkg/chronos import pkg/chronos
import pkg/codex/utils/iter import pkg/codex/utils/iter
import pkg/codex/utils/asyncresultiterator import pkg/codex/utils/asyncresultiter
import ../../asynctest import ../../asynctest
import ../helpers import ../helpers
asyncchecksuite "Test AsyncResultIterator": asyncchecksuite "Test AsyncResultIter":
test "Should be finished": test "Should be finished":
let iter = AsyncResultIterator[int].empty() let iter = AsyncResultIter[int].empty()
check: check:
iter.finished == true iter.finished == true
@ -24,7 +24,7 @@ asyncchecksuite "Test AsyncResultIterator":
fut.complete(success(intIter.next())) fut.complete(success(intIter.next()))
return fut return fut
let iter = AsyncResultIterator[int].new(asyncGen, () => intIter.finished) let iter = AsyncResultIter[int].new(asyncGen, () => intIter.finished)
var collected: seq[int] var collected: seq[int]
for iFut in iter: for iFut in iter:
@ -37,11 +37,10 @@ asyncchecksuite "Test AsyncResultIterator":
check collected == expectedSeq check collected == expectedSeq
let nextRes = await iter.next() let nextRes = await iter.next()
assert nextRes.isFailure assert nextRes.isFailure
check nextRes.error.msg == check nextRes.error.msg == "AsyncResultIter is finished but next item was requested"
"AsyncResultIterator is finished but next item was requested"
test "getting async iter for simple sync range iterator": test "getting async iter for simple sync range iterator":
let iter1 = AsyncResultIterator[int].new(0 ..< 5) let iter1 = AsyncResultIter[int].new(0 ..< 5)
var collected: seq[int] var collected: seq[int]
for iFut in iter1: for iFut in iter1:
@ -54,7 +53,7 @@ asyncchecksuite "Test AsyncResultIterator":
collected == @[0, 1, 2, 3, 4] collected == @[0, 1, 2, 3, 4]
test "Should map each item using `map`": test "Should map each item using `map`":
let iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) let iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
let iter2 = map[int, string]( let iter2 = map[int, string](
iter1, iter1,
@ -78,7 +77,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Should leave only odd items using `filter`": test "Should leave only odd items using `filter`":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = await filter[int]( iter2 = await filter[int](
iter1, iter1,
proc(i: ?!int): Future[bool] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[bool] {.async: (raises: [CancelledError]).} =
@ -101,7 +100,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Should leave only odd items using `mapFilter`": test "Should leave only odd items using `mapFilter`":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = await mapFilter[int, string]( iter2 = await mapFilter[int, string](
iter1, iter1,
proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} =
@ -124,7 +123,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `map` when finish on error is true": test "Collecting errors on `map` when finish on error is true":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = map[int, string]( iter2 = map[int, string](
iter1, iter1,
proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} =
@ -152,7 +151,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `map` when finish on error is false": test "Collecting errors on `map` when finish on error is false":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = map[int, string]( iter2 = map[int, string](
iter1, iter1,
proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} =
@ -181,7 +180,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `map` when errors are mixed with successes": test "Collecting errors on `map` when errors are mixed with successes":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = map[int, string]( iter2 = map[int, string](
iter1, iter1,
proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} =
@ -210,7 +209,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `mapFilter` when finish on error is true": test "Collecting errors on `mapFilter` when finish on error is true":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = await mapFilter[int, string]( iter2 = await mapFilter[int, string](
iter1, iter1,
proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} =
@ -240,7 +239,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `mapFilter` when finish on error is false": test "Collecting errors on `mapFilter` when finish on error is false":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
iter2 = await mapFilter[int, string]( iter2 = await mapFilter[int, string](
iter1, iter1,
proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} =
@ -271,7 +270,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `filter` when finish on error is false": test "Collecting errors on `filter` when finish on error is false":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5) iter1 = AsyncResultIter[int].new(0 ..< 5)
iter2 = map[int, string]( iter2 = map[int, string](
iter1, iter1,
proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} =
@ -314,7 +313,7 @@ asyncchecksuite "Test AsyncResultIterator":
test "Collecting errors on `filter` when finish on error is true": test "Collecting errors on `filter` when finish on error is true":
let let
iter1 = AsyncResultIterator[int].new(0 ..< 5) iter1 = AsyncResultIter[int].new(0 ..< 5)
iter2 = map[int, string]( iter2 = map[int, string](
iter1, iter1,
proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[?!string] {.async: (raises: [CancelledError]).} =
@ -383,9 +382,9 @@ asyncchecksuite "Test AsyncResultIterator":
# cancellation of the async predicate function. # cancellation of the async predicate function.
let fut: Future[Option[?!string]].Raising([CancelledError]) = let fut: Future[Option[?!string]].Raising([CancelledError]) =
Future[Option[?!string]].Raising([CancelledError]).init("testasyncresultiterator") Future[Option[?!string]].Raising([CancelledError]).init("testasyncresultiter")
let iter1 = AsyncResultIterator[int].new(0 ..< 5).delayBy(10.millis) let iter1 = AsyncResultIter[int].new(0 ..< 5).delayBy(10.millis)
let iter2 = await mapFilter[int, string]( let iter2 = await mapFilter[int, string](
iter1, iter1,
proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} = proc(i: ?!int): Future[Option[?!string]] {.async: (raises: [CancelledError]).} =