fix: continue to read after readableEnded
This commit is contained in:
parent
c8822aeffe
commit
33d42034fc
@ -24,16 +24,12 @@ export const isWritableEndedImpl = (s) => () => s.writableEnded;
|
|||||||
/** @type {(s: Stream.Writable | Stream.Transform) => () => void} */
|
/** @type {(s: Stream.Writable | Stream.Transform) => () => void} */
|
||||||
export const endImpl = (s) => () => s.end();
|
export const endImpl = (s) => () => s.end();
|
||||||
|
|
||||||
/** @type {<WriteResult>(o: {ok: WriteResult, wouldBlock: WriteResult, closed: WriteResult}) => (s: Stream.Writable | Stream.Transform) => (a: unknown) => () => WriteResult} */
|
/** @type {<WriteResult>(o: {ok: WriteResult, wouldBlock: WriteResult}) => (s: Stream.Writable | Stream.Transform) => (a: unknown) => () => WriteResult} */
|
||||||
export const writeImpl =
|
export const writeImpl =
|
||||||
({ ok, wouldBlock, closed }) =>
|
({ ok, wouldBlock }) =>
|
||||||
(s) =>
|
(s) =>
|
||||||
(a) =>
|
(a) =>
|
||||||
() => {
|
() => {
|
||||||
if (s.writableEnded) {
|
|
||||||
return closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.write(a)) {
|
if (s.write(a)) {
|
||||||
return ok;
|
return ok;
|
||||||
} else {
|
} else {
|
||||||
@ -41,15 +37,11 @@ export const writeImpl =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @type {<ReadResult>(o: {just: (_a: unknown) => ReadResult, wouldBlock: ReadResult, closed: ReadResult}) => (s: Stream.Readable | Stream.Transform) => () => ReadResult} */
|
/** @type {<ReadResult>(o: {just: (_a: unknown) => ReadResult, wouldBlock: ReadResult}) => (s: Stream.Readable | Stream.Transform) => () => ReadResult} */
|
||||||
export const readImpl =
|
export const readImpl =
|
||||||
({ just, closed, wouldBlock }) =>
|
({ just, wouldBlock }) =>
|
||||||
(s) =>
|
(s) =>
|
||||||
() => {
|
() => {
|
||||||
if (s.readableEnded) {
|
|
||||||
return closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
const a = s.read();
|
const a = s.read();
|
||||||
if (a === null) {
|
if (a === null) {
|
||||||
return wouldBlock;
|
return wouldBlock;
|
||||||
|
@ -26,7 +26,6 @@ import Unsafe.Coerce (unsafeCoerce)
|
|||||||
|
|
||||||
data ReadResult a
|
data ReadResult a
|
||||||
= ReadWouldBlock
|
= ReadWouldBlock
|
||||||
| ReadClosed
|
|
||||||
| ReadJust a
|
| ReadJust a
|
||||||
|
|
||||||
derive instance Generic (ReadResult a) _
|
derive instance Generic (ReadResult a) _
|
||||||
@ -37,7 +36,6 @@ instance Show (ReadResult a) where
|
|||||||
|
|
||||||
data WriteResult
|
data WriteResult
|
||||||
= WriteWouldBlock
|
= WriteWouldBlock
|
||||||
| WriteClosed
|
|
||||||
| WriteOk
|
| WriteOk
|
||||||
|
|
||||||
derive instance Generic WriteResult _
|
derive instance Generic WriteResult _
|
||||||
@ -45,8 +43,8 @@ derive instance Eq WriteResult
|
|||||||
instance Show WriteResult where
|
instance Show WriteResult where
|
||||||
show = genericShow
|
show = genericShow
|
||||||
|
|
||||||
type ReadResultFFI a = { closed :: ReadResult a, wouldBlock :: ReadResult a, just :: a -> ReadResult a }
|
type ReadResultFFI a = { wouldBlock :: ReadResult a, just :: a -> ReadResult a }
|
||||||
type WriteResultFFI = { closed :: WriteResult, wouldBlock :: WriteResult, ok :: WriteResult }
|
type WriteResultFFI = { wouldBlock :: WriteResult, ok :: WriteResult }
|
||||||
|
|
||||||
foreign import data Writable :: Type -> Type
|
foreign import data Writable :: Type -> Type
|
||||||
foreign import data Readable :: Type -> Type
|
foreign import data Readable :: Type -> Type
|
||||||
@ -64,10 +62,10 @@ foreign import needsDrainImpl :: forall s. s -> Effect Boolean
|
|||||||
foreign import readableLengthImpl :: forall s. s -> Effect Int
|
foreign import readableLengthImpl :: forall s. s -> Effect Int
|
||||||
|
|
||||||
readResultFFI :: forall a. ReadResultFFI a
|
readResultFFI :: forall a. ReadResultFFI a
|
||||||
readResultFFI = { closed: ReadClosed, wouldBlock: ReadWouldBlock, just: ReadJust }
|
readResultFFI = { wouldBlock: ReadWouldBlock, just: ReadJust }
|
||||||
|
|
||||||
writeResultFFI :: WriteResultFFI
|
writeResultFFI :: WriteResultFFI
|
||||||
writeResultFFI = { closed: WriteClosed, wouldBlock: WriteWouldBlock, ok: WriteOk }
|
writeResultFFI = { wouldBlock: WriteWouldBlock, ok: WriteOk }
|
||||||
|
|
||||||
class Stream :: Type -> Constraint
|
class Stream :: Type -> Constraint
|
||||||
class Stream s where
|
class Stream s where
|
||||||
|
@ -40,8 +40,13 @@ fromReadable r =
|
|||||||
res <- liftEffect $ O.read r
|
res <- liftEffect $ O.read r
|
||||||
case res of
|
case res of
|
||||||
O.ReadJust a -> yield (Just a) $> Loop { error, cancel }
|
O.ReadJust a -> yield (Just a) $> Loop { error, cancel }
|
||||||
O.ReadWouldBlock -> liftAff (O.awaitReadableOrClosed r) $> Loop { error, cancel }
|
O.ReadWouldBlock -> do
|
||||||
O.ReadClosed -> yield Nothing *> cleanup cancel
|
ended <- liftEffect $ O.isReadableEnded r
|
||||||
|
if ended then do
|
||||||
|
yield Nothing
|
||||||
|
cleanup cancel
|
||||||
|
else
|
||||||
|
liftAff (O.awaitReadableOrClosed r) $> Loop { error, cancel }
|
||||||
in
|
in
|
||||||
do
|
do
|
||||||
e <- liftEffect $ O.withErrorST r
|
e <- liftEffect $ O.withErrorST r
|
||||||
@ -66,14 +71,16 @@ fromWritable w =
|
|||||||
|
|
||||||
needsDrain <- liftEffect $ O.needsDrain w
|
needsDrain <- liftEffect $ O.needsDrain w
|
||||||
when needsDrain $ liftAff $ O.awaitWritableOrClosed w
|
when needsDrain $ liftAff $ O.awaitWritableOrClosed w
|
||||||
ma <- await
|
|
||||||
case ma of
|
ended <- liftEffect $ O.isWritableEnded w
|
||||||
Nothing -> cleanup cancel
|
if ended then
|
||||||
Just a -> do
|
cleanup cancel
|
||||||
res <- liftEffect $ O.write w a
|
else
|
||||||
case res of
|
await >>= case _ of
|
||||||
O.WriteClosed -> cleanup cancel
|
Nothing -> cleanup cancel
|
||||||
_ -> pure $ Loop { error, cancel }
|
Just a -> do
|
||||||
|
void $ liftEffect $ O.write w a
|
||||||
|
pure $ Loop { error, cancel }
|
||||||
in
|
in
|
||||||
do
|
do
|
||||||
r <- liftEffect $ O.withErrorST w
|
r <- liftEffect $ O.withErrorST w
|
||||||
@ -111,18 +118,19 @@ fromTransform t =
|
|||||||
for_ err throwError
|
for_ err throwError
|
||||||
|
|
||||||
needsDrain <- liftEffect $ O.needsDrain t
|
needsDrain <- liftEffect $ O.needsDrain t
|
||||||
|
ended <- liftEffect $ O.isWritableEnded t
|
||||||
if needsDrain then do
|
if needsDrain then do
|
||||||
liftAff $ delay $ wrap 0.0
|
liftAff $ delay $ wrap 0.0
|
||||||
yieldWhileReadable
|
yieldWhileReadable
|
||||||
pure $ Loop { error, cancel }
|
pure $ Loop { error, cancel }
|
||||||
else do
|
else if ended then
|
||||||
ma <- await
|
cleanup cancel
|
||||||
case ma of
|
else
|
||||||
|
await >>= case _ of
|
||||||
Nothing -> cleanup cancel
|
Nothing -> cleanup cancel
|
||||||
Just a' -> do
|
Just a' -> do
|
||||||
res <- liftEffect $ O.write t a'
|
res <- liftEffect $ O.write t a'
|
||||||
case res of
|
case res of
|
||||||
O.WriteClosed -> cleanup cancel
|
|
||||||
O.WriteOk -> do
|
O.WriteOk -> do
|
||||||
maybeYield1
|
maybeYield1
|
||||||
pure $ Loop { error, cancel }
|
pure $ Loop { error, cancel }
|
||||||
|
Loading…
Reference in New Issue
Block a user