nwaku/vendor/nim-faststreams/faststreams/chronos_adapters.nim

104 lines
3.9 KiB
Nim

import
chronos,
inputs, outputs, buffers, multisync
export
chronos, fsMultiSync
type
ChronosInputStream* = ref object of InputStream
transport: StreamTransport
allowWaitFor: bool
ChronosOutputStream* = ref object of OutputStream
transport: StreamTransport
allowWaitFor: bool
const
readingErrMsg = "Failed to read from Chronos transport"
writingErrMsg = "Failed to write to Chronos transport"
closingErrMsg = "Failed to close Chronos transport"
writeIncompleteErrMsg = "Failed to write all bytes to Chronos transport"
proc chronosCloseWait(t: StreamTransport)
{.async, raises: [Defect, IOError].} =
fsTranslateErrors closingErrMsg:
await t.closeWait()
proc chronosReadOnce(s: ChronosInputStream,
dst: pointer, dstLen: Natural): Future[Natural] {.async.} =
fsTranslateErrors readingErrMsg:
return implementSingleRead(s.buffers, dst, dstLen, ReadFlags {},
readStartAddr, readLen):
await s.transport.readOnce(readStartAddr, readLen)
proc chronosWrites(s: ChronosOutputStream, src: pointer, srcLen: Natural) {.async.} =
fsTranslateErrors writeIncompleteErrMsg:
implementWrites(s.buffers, src, srcLen, "StreamTransport",
writeStartAddr, writeLen):
await s.transport.write(writeStartAddr, writeLen)
# TODO: Use the Raising type here
let chronosInputVTable = InputStreamVTable(
readSync: proc (s: InputStream, dst: pointer, dstLen: Natural): Natural
{.nimcall, gcsafe, raises: [IOError, Defect].} =
fsTranslateErrors "Unexpected exception from Chronos async macro":
var cs = ChronosInputStream(s)
fsAssert cs.allowWaitFor
return waitFor chronosReadOnce(cs, dst, dstLen)
,
readAsync: proc (s: InputStream, dst: pointer, dstLen: Natural): Future[Natural]
{.nimcall, gcsafe, raises: [IOError, Defect].} =
fsTranslateErrors "Unexpected exception from merely forwarding a future":
return chronosReadOnce(ChronosInputStream s, dst, dstLen)
,
closeSync: proc (s: InputStream)
{.nimcall, gcsafe, raises: [IOError, Defect].} =
fsTranslateErrors closingErrMsg:
s.closeFut = ChronosInputStream(s).transport.close()
,
closeAsync: proc (s: InputStream): Future[void]
{.nimcall, gcsafe, raises: [IOError, Defect].} =
chronosCloseWait ChronosInputStream(s).transport
)
func chronosInput*(s: StreamTransport,
pageSize = defaultPageSize,
allowWaitFor = false): AsyncInputStream =
AsyncInputStream ChronosInputStream(
vtable: vtableAddr chronosInputVTable,
buffers: initPageBuffers(pageSize),
transport: s,
allowWaitFor: allowWaitFor)
let chronosOutputVTable = OutputStreamVTable(
writeSync: proc (s: OutputStream, src: pointer, srcLen: Natural)
{.nimcall, gcsafe, raises: [IOError, Defect].} =
var cs = ChronosOutputStream(s)
fsAssert cs.allowWaitFor
waitFor chronosWrites(cs, src, srcLen)
,
writeAsync: proc (s: OutputStream, src: pointer, srcLen: Natural): Future[void]
{.nimcall, gcsafe, raises: [IOError, Defect].} =
chronosWrites(ChronosOutputStream s, src, srcLen)
,
closeSync: proc (s: OutputStream)
{.nimcall, gcsafe, raises: [IOError, Defect].} =
fsTranslateErrors closingErrMsg:
s.closeFut = close ChronosOutputStream(s).transport
,
closeAsync: proc (s: OutputStream): Future[void]
{.nimcall, gcsafe, raises: [IOError, Defect].} =
chronosCloseWait ChronosOutputStream(s).transport
)
func chronosOutput*(s: StreamTransport,
pageSize = defaultPageSize,
allowWaitFor = false): AsyncOutputStream =
AsyncOutputStream ChronosOutputStream(
vtable: vtableAddr(chronosOutputVTable),
buffers: initPageBuffers(pageSize),
transport: s,
allowWaitFor: allowWaitFor)